🧬
Inheritance
Chapter 4 · OOP Series
Inheritance
— Kế Thừa
Tái sử dụng code thông minh — class con thừa hưởng tất cả từ class cha, rồi mở rộng thêm!
Phần 1 — Kế thừa là gì?
Class con kế thừa từ class cha
Inheritance (kế thừa) cho phép một class con (child) thừa hưởng tất cả attributes và methods từ class cha (parent), rồi thêm hoặc thay đổi cho phù hợp.
🧬
Như di truyền trong gia đình!
Con cái thừa hưởng đặc điểm từ bố mẹ (tóc đen, da ngăm) nhưng cũng có nét riêng của mình. Class con cũng vậy — nhận toàn bộ từ class cha, rồi thêm hoặc ghi đè theo nhu cầu!
🐾 DongVat
ten, tuoi — an(), ngu()
ten, tuoi — an(), ngu()
🐕 Cho
giong — sua()
giong — sua()
🐈 Meo
mau_long — keu()
mau_long — keu()
🐦 Chim
sải_cánh — bay()
sải_cánh — bay()
♻️ DRY — Don't Repeat Yourself! Không cần viết lại
ten, tuoi, an(), ngu() cho từng loài — viết một lần ở class cha, các class con tự có!Phần 2 — Cú pháp kế thừa
Cú pháp: class Con(Cha):
# ── Class CHA ──────────────────────────── class DongVat: def __init__(self, ten, tuoi): self.ten = ten self.tuoi = tuoi def an(self): print(f"{self.ten} đang ăn... 🍖") def ngu(self): print(f"{self.ten} đang ngủ... 💤") # ── Class CON kế thừa từ DongVat ───────── class Cho(DongVat): ← (DongVat) = kế thừa! def __init__(self, ten, tuoi, giong): super().__init__(ten, tuoi) ← gọi __init__ của cha! self.giong = giong ← thuộc tính riêng của Cho def sua(self): ← method riêng của Cho print(f"{self.ten}: Gâu gâu! 🐕") # ── Test ───────────────────────────────── rex = Cho("Rex", 3, "Husky") rex.an() # ✅ kế thừa từ DongVat rex.ngu() # ✅ kế thừa từ DongVat rex.sua() # ✅ method riêng của Cho print(rex.giong)
Rex đang ăn... 🍖
Rex đang ngủ... 💤
Rex: Gâu gâu! 🐕
Husky
Rex đang ngủ... 💤
Rex: Gâu gâu! 🐕
Husky
Phần 3 — super() là gì?
super() — Gọi lên class cha
super() trả về một đối tượng đại diện cho class cha, cho phép bạn gọi method của cha từ bên trong class con.
class NhanVien: def __init__(self, ten, luong): self.ten = ten self.luong = luong def gioi_thieu(self): print(f"Tôi là {self.ten}, lương {self.luong:,}đ") class QuanLy(NhanVien): def __init__(self, ten, luong, phong_ban): super().__init__(ten, luong) ← không cần lặp lại code! self.phong_ban = phong_ban def gioi_thieu(self): ← OVERRIDE method cha super().gioi_thieu() ← gọi phần cha trước print(f"Phụ trách phòng: {self.phong_ban}") nv = NhanVien("An", 8_000_000) ql = QuanLy("Bình", 15_000_000, "Kỹ thuật") nv.gioi_thieu() print("---") ql.gioi_thieu()
Tôi là An, lương 8,000,000đ
---
Tôi là Bình, lương 15,000,000đ
Phụ trách phòng: Kỹ thuật
---
Tôi là Bình, lương 15,000,000đ
Phụ trách phòng: Kỹ thuật
🔑 super() có 2 tác dụng chính: (1) Gọi
__init__ cha để không phải viết lại thuộc tính. (2) Gọi method cha từ trong method con đã override — mở rộng thay vì thay thế hoàn toàn!Phần 4 — Method Override
Override — Ghi đè method của cha
Class con có thể override (ghi đè) bất kỳ method nào của class cha bằng cách định nghĩa lại cùng tên:
class HinhDang: def dien_tich(self): return 0 ← mặc định ở cha def mo_ta(self): print(f"Diện tích: {self.dien_tich():.2f}") class HinhVuong(HinhDang): def __init__(self, canh): self.canh = canh def dien_tich(self): ← OVERRIDE return self.canh ** 2 class HinhTron(HinhDang): def __init__(self, r): self.r = r def dien_tich(self): ← OVERRIDE return 3.14159 * self.r ** 2 for h in [HinhVuong(5), HinhTron(4)]: h.mo_ta() ← cùng gọi mo_ta() nhưng dien_tich() khác nhau!
Diện tích: 25.00
Diện tích: 50.27
Diện tích: 50.27
Đây là nền tảng của Polymorphism! Cùng gọi
mo_ta() nhưng mỗi loại hình dạng tính diện tích theo cách riêng. Bạn sẽ học sâu hơn ở Chapter 5!Phần 5 — isinstance() & issubclass()
Kiểm tra quan hệ kế thừa
print(isinstance(rex, Cho)) # True — rex là Cho print(isinstance(rex, DongVat)) # True — rex cũng là DongVat! print(issubclass(Cho, DongVat)) # True — Cho là con của DongVat print(issubclass(Cho, Meo)) # False — Cho không kế thừa Meo print(rex.__class__.__name__) # "Cho"
True
True
True
False
Cho
True
True
False
Cho
Phần 6 — Bài tập tổng hợp
🚀 Dự án nhỏ — RPG Preview
Hệ thống nhân vật game RPG
class NhanVatGame: ← CLASS CHA def __init__(self, ten, hp, suc_manh): self.ten = ten self.hp = hp self.suc_manh = suc_manh def tan_cong(self, muc_tieu): print(f"⚔️ {self.ten} tấn công {muc_tieu.ten} -{self.suc_manh} HP") muc_tieu.hp -= self.suc_manh def stats(self): print(f" [{self.ten}] HP:{self.hp} | STR:{self.suc_manh}") class ChienBinh(NhanVatGame): ← CLASS CON def __init__(self, ten): super().__init__(ten, hp=150, suc_manh=25) self.giap = 10 ← thuộc tính riêng def chan_don(self): ← skill riêng print(f"🛡️ {self.ten} chắn đòn! Giảm {self.giap} sát thương") class PhapSu(NhanVatGame): def __init__(self, ten): super().__init__(ten, hp=80, suc_manh=40) self.mana = 100 def phep_thuat(self, muc_tieu): if self.mana >= 30: self.mana -= 30 muc_tieu.hp -= 60 print(f"🔮 {self.ten} tung phép! -60 HP") chien_binh = ChienBinh("Arthur") phap_su = PhapSu("Merlin") chien_binh.tan_cong(phap_su) phap_su.phep_thuat(chien_binh) print("\n── Sau trận ──") for nv in [chien_binh, phap_su]: nv.stats()
⚔️ Arthur tấn công Merlin -25 HP
🔮 Merlin tung phép! -60 HP
── Sau trận ──
[Arthur] HP:90 | STR:25
[Merlin] HP:55 | STR:40
🔮 Merlin tung phép! -60 HP
── Sau trận ──
[Arthur] HP:90 | STR:25
[Merlin] HP:55 | STR:40
🧩 Kiểm tra nhanh!
Chapter 4 — Inheritance
Cú pháp kế thừa trong Python?
→ class Con(Cha):
→ class Con(Cha):
super() dùng để làm gì?
→ Gọi method/init của class cha
→ Gọi method/init của class cha
Override là gì?
→ Class con định nghĩa lại method của cha
→ Class con định nghĩa lại method của cha
isinstance(rex, DongVat) trả về gì?
→ True — vì Cho kế thừa DongVat
→ True — vì Cho kế thừa DongVat