menu_book LESSON MODE

OOP Ch.2 — Methods

calendar_today Đăng 29 May 2026
OOP Ch.2 — Methods
school

NOW LEARNING

OOP Ch.2 — Methods

🏗️ OOP Series · Lập trình Hướng đối tượng với Python
⚡
Chapter 2 · OOP Series

Methods
— Hành Động Của Object

Class không chỉ lưu dữ liệu — nó còn biết làm những việc cụ thể. Đó chính là sức mạnh của Methods!

🔄

Bạn đã biết từ Chapter 1

🏛️ class Tên: 🔧 __init__(self, ...) 📦 self.thuoc_tinh 🎯 Object = Class() 🔵 PascalCase

Chapter 2 xây lên trên nền đó: thêm methods (phương thức) để object không chỉ có dữ liệu mà còn biết làm việc!

🎬

Method — Hành động của Object

Nếu thuộc tính (attribute) là những thứ object có, thì method là những thứ object có thể làm. Method về bản chất là hàm (def) được định nghĩa bên trong một Class.

🤖
Object = Robot có thuộc tính + hành động Robot có: màu sắc, chiều cao, tên (thuộc tính).
Robot biết: đi, nói chuyện, nhặt đồ (methods).
Thiếu method thì object chỉ là… "đống dữ liệu" thôi!
Thuộc tính (Attribute)Method Những thứ object CÓ
self.ten, self.tuoi Những thứ object LÀM ĐƯỢC
chao(), tinh_diem(), chay() Lưu dữ liệu — là biến Xử lý logic — là hàm (có self)
✍️

Cú pháp — Method luôn có self

Method được khai báo như hàm thông thường, nhưng luôn có tham số đầu tiên là self — đây là điểm khác biệt duy nhất!

📄 hoc_sinh.py
class HocSinh:
    def __init__(self, ten, diem):
        self.ten  = ten
        self.diem = diem
    ①
    def chao(self):             ← ② tên method — không tham số ngoài self
        print(f"Chào! Tôi là {self.ten}")  ← ③ dùng self để lấy thuộc tính
    ④
    def xep_loai(self):          ← method thứ hai
        if self.diem >= 8:
            return "Giỏi 🌟"
        return "Khá ✅"
defTừ khoá khai báo method — giống hàm thông thường
selfTham số đầu tiên bắt buộc — đại diện cho object đang gọi method
tên methodsnake_case — mô tả hành động: chao(), tinh_diem(), chay_that_nhanh()
self.thuoc_tinhBên trong method, truy cập thuộc tính object qua self
returnMethod có thể trả về giá trị hoặc chỉ in ra — tuỳ mục đích
# Gọi method bằng dấu chấm (.) — giống truy cập thuộc tính
nam = HocSinh("Nam", 8.5)

nam.chao()             # Gọi method — không cần truyền self!
loai = nam.xep_loai()
print(loai)
Chào! Tôi là Nam
Giỏi 🌟
🎯 Quy tắc gọi method: Khi bạn gọi nam.chao(), Python tự động truyền nam vào tham số self. Bạn không cần tự làm điều này!
🔍

Bí mật của self — Python làm điều kỳ diệu!

Nhiều bạn thắc mắc: "Tại sao gọi nam.chao() không cần truyền self?" — Python xử lý điều đó ngầm bên trong!

👤
Bạn viết
nam.chao()
→
🐍
Python dịch thành
HocSinh.chao(nam)
→
⚙️
Method nhận
self = nam
class ViDu:
    def __init__(self, gia_tri):
        self.gia_tri = gia_tri

    def hien_thi(self):
        print(f"self là: {self}")
        print(f"gia_tri: {self.gia_tri}")

a = ViDu(42)
b = ViDu(99)

a.hien_thi()    # self = a
print("---")
b.hien_thi()    # self = b (khác rồi!)
self là: <__main__.ViDu object at 0x...>
gia_tri: 42
---
self là: <__main__.ViDu object at 0x...>
gia_tri: 99

Hai lần gọi cùng một method hien_thi() nhưng self khác nhau — self chính là object nào đang gọi method đó!

📥

Truyền tham số vào Method

Method hoàn toàn có thể nhận thêm tham số — chỉ cần thêm vào sau self:

class TaiKhoanNganHang:
    def __init__(self, chu_tk, so_du=0):
        self.chu_tk  = chu_tk
        self.so_du   = so_du
        self.lich_su = []

    def nap_tien(self, so_tien):        ← tham số ngoài self
        self.so_du += so_tien
        self.lich_su.append(f"+{so_tien:,}đ")
        print(f"✅ Nạp {so_tien:,}đ — Số dư: {self.so_du:,}đ")

    def rut_tien(self, so_tien):        ← tham số ngoài self
        if so_tien > self.so_du:
            print("❌ Số dư không đủ!")
            return
        self.so_du -= so_tien
        self.lich_su.append(f"-{so_tien:,}đ")
        print(f"💸 Rút {so_tien:,}đ — Còn lại: {self.so_du:,}đ")

    def xem_lich_su(self):               ← không tham số ngoài
        print(f"\n📋 Lịch sử TK của {self.chu_tk}:")
        for gd in self.lich_su:
            print(f"  {gd}")

# Sử dụng
tk = TaiKhoanNganHang("Nguyễn Văn Nam", 500_000)
tk.nap_tien(200_000)
tk.rut_tien(100_000)
tk.rut_tien(700_000)     # thử rút quá số dư
tk.xem_lich_su()
✅ Nạp 200,000đ — Số dư: 700,000đ
💸 Rút 100,000đ — Còn lại: 600,000đ
❌ Số dư không đủ!

📋 Lịch sử TK của Nguyễn Văn Nam:
  +200,000đ
  -100,000đ
🔗

Method có thể gọi method khác trong cùng Class

Bên trong một method, bạn dùng self.ten_method() để gọi method khác của cùng object:

class HocSinh:
    def __init__(self, ten, ds_diem):
        self.ten     = ten
        self.ds_diem = ds_diem

    def tinh_tb(self):
        return sum(self.ds_diem) / len(self.ds_diem)

    def xep_loai(self):
        tb = self.tinh_tb()      ← gọi method khác qua self!
        if   tb >= 8:   return "Giỏi 🌟"
        elif tb >= 6.5: return "Khá ✅"
        else:           return "Trung Bình 📝"

    def bao_cao(self):
        tb   = self.tinh_tb()     ← dùng lại method khác
        loai = self.xep_loai()    ← và method khác nữa!
        print(f"┌─── Học Bạ ───────────")
        print(f"│ Tên   : {self.ten}")
        print(f"│ TB    : {tb:.1f}")
        print(f"│ Loại  : {loai}")
        print(f"└──────────────────────")

nam = HocSinh("Nguyễn Nam", [8, 9, 7.5, 8.5, 10])
nam.bao_cao()
┌─── Học Bạ ───────────
│ Tên : Nguyễn Nam
│ TB : 8.6
│ Loại : Giỏi 🌟
└──────────────────────
♻️ Tái sử dụng method! Method bao_cao() không tính lại từ đầu — nó gọi tinh_tb() và xep_loai() đã có sẵn. Đây chính là sức mạnh của OOP: mỗi method làm một việc, kết hợp lại thành hệ thống!
🗂️

Python có 3 loại Method — Ch.2 học loại chính!

⭐ Instance Method
  • Loại phổ biến nhất
  • Tham số đầu là self
  • Truy cập được thuộc tính object
  • Đang học ở Chapter 2
🔵 Class Method
  • Dùng @classmethod
  • Tham số đầu là cls
  • Truy cập được class, không phải object
  • Học ở Chapter 7
⚪ Static Method
  • Dùng @staticmethod
  • Không có self hay cls
  • Hàm tiện ích trong class
  • Học ở Chapter 7
📚 Chỉ cần nắm vững Instance Method trước — đó là 90% công việc hằng ngày của lập trình viên OOP!
📏

Quy tắc vàng khi viết Method

✅Mỗi method chỉ làm một việc duy nhất — tên nói lên tất cả: tinh_tong(), xep_loai()
✅Đặt tên động từ + danh từ: nap_tien(), in_bao_cao(), cap_nhat_diem()
✅Method ngắn gọn — nếu dài hơn 15 dòng, hãy tách thành nhiều method nhỏ
❌Đừng đặt tên chung chung: xu_ly(), ham1(), lam_viec() — không biết làm gì!
❌Đừng để method làm quá nhiều thứ khác nhau — khó đọc, khó sửa!
❌Quên self ở tham số đầu — Python sẽ báo lỗi ngay!
🚀 Dự án nhỏ

Xây dựng Class QuanLyLop

Kết hợp thuộc tính và nhiều method để tạo hệ thống quản lý lớp học hoàn chỉnh:

class QuanLyLop:
    def __init__(self, ten_lop):
        self.ten_lop   = ten_lop
        self.hoc_sinh  = {}     # {ten: [diem]}

    def them_hoc_sinh(self, ten):
        if ten not in self.hoc_sinh:
            self.hoc_sinh[ten] = []
            print(f"➕ Đã thêm: {ten}")
        else:
            print(f"⚠️  {ten} đã có trong lớp!")

    def nhap_diem(self, ten, diem):
        if ten in self.hoc_sinh:
            self.hoc_sinh[ten].append(diem)
        else:
            print(f"❌ Không tìm thấy: {ten}")

    def _tinh_tb(self, ten):            ← method "nội bộ"
        ds = self.hoc_sinh[ten]
        return round(sum(ds) / len(ds), 1) if ds else 0

    def bao_cao_lop(self):
        print(f"\n{'═'*36}")
        print(f"  📋 BÁO CÁO LỚP {self.ten_lop.upper()}")
        print(f"{'─'*36}")
        for ten, ds in self.hoc_sinh.items():
            tb = self._tinh_tb(ten)     ← gọi method khác
            xl = "Giỏi" if tb >= 8 else "Khá" if tb >= 6.5 else "TB"
            print(f"  {ten:12} TB: {tb:4}  [{xl}]")
        print(f"{'═'*36}\n")

# ── Sử dụng ─────────────────────────────
lop8a = QuanLyLop("8A")

for hs in ["Nam", "Lan", "Bình"]:
    lop8a.them_hoc_sinh(hs)

lop8a.nhap_diem("Nam",  8.5); lop8a.nhap_diem("Nam",  9.0)
lop8a.nhap_diem("Lan",  7.0); lop8a.nhap_diem("Lan",  6.5)
lop8a.nhap_diem("Bình", 9.5); lop8a.nhap_diem("Bình", 8.0)

lop8a.bao_cao_lop()
➕ Đã thêm: Nam
➕ Đã thêm: Lan
➕ Đã thêm: Bình

════════════════════════════════════
  📋 BÁO CÁO LỚP 8A
────────────────────────────────────
  Nam         TB: 8.8 [Giỏi]
  Lan         TB: 6.8 [Khá]
  Bình        TB: 8.8 [Giỏi]
════════════════════════════════════
🌟
Chú ý tên method _tinh_tb() — dấu gạch dưới đầu! Quy ước _ten_method có nghĩa là "method nội bộ — chỉ dùng trong class". Bạn sẽ học sâu hơn về điều này ở Chapter 3: Encapsulation!

🧩 Kiểm tra nhanh!

Ôn lại kiến thức Chapter 2 — Methods!

1️⃣Method khác hàm thông thường ở điểm nào?
→ Nằm trong class và có tham số self đầu tiên
2️⃣Gọi method của object như thế nào?
→ object.ten_method(tham_so)
3️⃣Bên trong method, gọi method khác bằng gì?
→ self.ten_method_khac()
4️⃣Method có thể không có return không?
→ Có — method chỉ in ra màn hình không cần return
OOP Series: Chapter 2 / 10
⚡
🔒
Tiếp theo · Chapter 3
Encapsulation — Đóng Gói Dữ Liệu
Học cách bảo vệ dữ liệu trong object: private/protected attributes, getter/setter và @property decorator.
→

NEXT STEP

Tiếp theo nên học gì

route