Kế thừa
Kế thừa trong lập trình là cách mở rộng nhanh chóng 1 class nhờ vào class có sẵn thay vì viết lại toàn bộ, class kế thừa sẽ thừa kế các thuộc tính, phương thức từ lớp được kế thừa và có thể sử dụng chúng như là của chính bản thân mình (lớp kế thừa).
Kế thừa giúp tiết kiệm được thời gian để viết code, dễ dàng bảo trì và mở rộng.
Trong Python có 2 loại kế thừa:
- Đơn kế thừa
- Đa kế thừa
Cú pháp
class ChildClass(ParentClass1[, ParentClass2, ...]): statement_1 . . statement_n
Ví dụ
#!/usr/bin/python
class Animal: def __init__(self, genus, age): self.genus = genus self.age = age def say(self): pass class Duck(Animal): def __init__(self): Animal.__init__(self, 'Dog', 10) def say(self): print ("Quack quack!")
Giải thích:
- Dòng 9: lớp
Duck
được khai báo kế thừa từ lớpAnimal
. - Dòng 10: phương thức
__init__
được override từ phương thức__init__
ở lớp cha (lớpAnimal
). - Dòng 11: cách gọi một phương thức từ lớp cha.
- Dòng 13: phương thức
say
được override lại từ phương thứcsay
ở lớp cha.
Một số tính chất cần lưu ý
Khi phương thức __init__
ở lớp con không được khai báo, nó sẽ dùng phương thức __init__
ở lớp cha.
Khác với các C++, trong Python chỉ có một loại kế thừa duy nhất là public
.
Trong Python các thuộc tính, phương thức của lớp không tồn tại khái niệm protected
như ở C++ mà chỉ tồn tại ở dạng private
và public
, được phân biệt dựa theo tên.
private
: tên được bắt đầu bằng 2 dấu gạch dưới__
và kết thúc tối đa là 1 dấu gạch dưới, ví dụ:__abc
,__xyz_
, ...public
: tên không phải tên của kiểuprivate
và đúng quy tắc đều làpublic
.
Ví dụ:
#!/usr/bin/python
class Animal: def __init__(self, genus, age): self.genus = genus self.age = age def say(self): pass class Duck(Animal): def __init__(self): Animal.__init__(self, 'Dog', 10) def say(self): print("Quack quack!") def __fly(self): print("Flap flap!") duck = Duck() duck.__fly()
Kết quả:
C:\Users\Thanh\Desktop>demo.py Traceback (most recent call last): File "C:\Users\Thanh\Desktop\demo.py", line 21, in <module> duck.__fly() AttributeError: 'Duck' object has no attribute '__fly'
Lỗi xảy ra vì phương thức __fly
trong lớp Duck
là private
nên không thể truy cập được từ bên ngoài lớp đó.
Duck Typing
Trong Python kiểu dữ liệu là kiểu động nên các lập trình viên thường quan tâm đến các thuộc tính, hàm của các đối tượng hơn là kiểu dữ liệu của chúng, phong cách này có tên là Duck Typing.
Ví dụ
#!/usr/bin/python class Person(): def say(self): print ("Hello STDIO!") def quackquack(duck): duck.say() person = Person() quackquack(person)
Hàm quackquack
truyền vào tham số vào là một đối tượng kiểu Duck
, tuy nhiên có thể dùng nó với một đối tượng kiểu Person
.