Phát biểu sai khi nói về kế thừa trong python

Trong bài này mình sẽ giải thích sâu hơn về kế thừa trong Python, nhất là kế thừa liên quan đến các mức độ truy cập private / protected và public trong Python.

Phát biểu sai khi nói về kế thừa trong python

Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Trong lập trình hướng đối tượng Python thì tính kế thừa rất quan trọng, nó giúp bạn thiết kế cấu trúc ứng dụng một cách khoa học, phân chia các lớp một cách tối ưu, lớp này có thể tái sử dụng dữ liệu của lớp khác.

1. Kế thừa trong Python là gì?

Kế thừa (Inheritance) là việc một lớp được khai báo kế thừa toàn bộ thuộc tính và phương thức của một lớp khác. Lớp được kế thừa ta gọi là lớp con, và lớp kế thừa ta gọi là lớp cha.

Lớp con có thể sử dụng toàn bộ dữ liệu khai báo ở mức độ protected public ở lớp cha. Riêng với private thì không được, vì đó là mức độ bảo mật cao nhất, chỉ sử dụng bên trong nội bộ của lớp cha.

Bài viết này được đăng tại [free tuts .net]

Nếu bạn chưa biêt về ba mức độ này thì hãy quay lại bài viết class trong Python để đọc nhé.

Cách khai báo kế thừa:

class lopCha:
    # Code của lớp cha

class lopCon(lopCha):
    # Code của lớp con

Ví dụ: Khao báo lớp XeDap kế thừa từ lớp Xe.

class Xe:
    # Code ...

class XeDap(Xe):
    # Code ...

Phần này bạn chỉ cần hiểu khái niệm và cú pháp thôi nhé, còn chi tiết cách dùng kế thừa trong Python thì chúng ta sẽ học ở những phần tiếp theo dưới đây.

2. Kế thừa thuộc tính và phương thức của lớp cha

Trong kế thừa Python thì đặc điểm hay nhất là lớp con co thể sử dụng dữ liệu của lớp cha, trừ trường hợp dữ liệu đó là private.

Ví dụ 1: Sử dụng thuộc tính của lớp cha

class Xe:
    name = 'Đây là tên xe'

class XeDap(Xe):
    def showName(self):
        # sử dụng thuộc tính name của lớp cha
        print(self.name)

# Cách dùng
d = XeDap()
d.showName()

Kết quả:

Ví dụ 2: Sử dụng phương thức của lớp cha

class Xe:
    name = ''
    def setName(self, name):
        self.name = name

class XeDap(Xe):
    def showName(self, name):
        # Sử dụng phương thức của lớp cha
        self.setName("Xe đạp")

        # sử dụng thuộc tính name của lớp cha
        print(self.name)

# Cách dùng
d = XeDap()
d.showName("Xe đạp")

Kết quả:

3. Kế thừa trong Python với hàm khởi tạo

Hàm khởi tạo trong Python sẽ được tự động gọi mỗi khi bạn tạo mới đối tượng. Nếu là class đơn thì quá dễ, trường hợp class có kế thừa thì câu hỏi đặt ra như sau:

Nếu cả lớp cha và lớp con đều có hàm khởi tạo thì Python sẽ sử dụng hàm nào?

Theo mức độ ưu tiên thì Python sẽ chạy hàm khởi tạo ở lớp con nhé các bạn.

class Xe:
    def __init__(self):
        print("Hàm khởi tạo lớp cha")

class XeDap(Xe):
    def __init__(self):
        print("Hàm khởi tạo lớp con")

# Cách dùng
d = XeDap()

Kết quả:

Nếu bạn muốn chạy hàm khởi tạo của lớp cha thì hãy gọi nó ở lớp con thông qua hàm supper() nhé.

class Xe:
    def __init__(self):
        print("Hàm khởi tạo lớp cha")

class XeDap(Xe):
    def __init__(self):
        # Gọi hàm khởi tạo lớp cha
        super().__init__()

        print("Hàm khởi tạo lớp con")

# Cách dùng
d = XeDap()

Kết quả:

Hoặc bạn cũng có thể sử dụng thông qua tên của lớp cha như ví dụ dưới đây.

class Xe:
    def __init__(self):
        print("Hàm khởi tạo lớp cha")

class XeDap(Xe):
    def __init__(self):
        # Gọi hàm khởi tạo lớp cha
        Xe.__init__(self)

        print("Hàm khởi tạo lớp con")

# Cách dùng
d = XeDap()

Trên là cách sử dụng tính kế thừa trong Python nói chung và trong lâp trình hướng đối tương Python nói riêng. Bài này mình sẽ dừng ở đây, bài tiếp theo chúng ta sẽ tìm hiểu đa kế thừa trong Python nhé.

Kế thừa trong lập trình hướng đối tượng cho phép chúng ta khai báo lớp mới sử dụng lại các hàm và thuộc tính của lớp cha cùng các chức năng mở rộng thêm. Trong bài viết này, Quantrimang sẽ cùng bạn học cách sử dụng tính kế thừa trong Python.

Kế thừa là gì?

Kế thừa (Inheritance) cho phép một lớp (class) có thể kế thừa các thuộc tính và phương thức từ các lớp khác đã được định nghĩa. Lớp đã có gọi là lớp cha (base class hoặc parent class), lớp mới phát sinh gọi là lớp con (child class hoặc derived class). Lớp con kế thừa tất cả thành phần của lớp cha, có thể mở rộng các thành phần kế thừa và bổ sung thêm các thành phần mới.

Cú pháp của kế thừa

class BaseClass:
Body of base class

class DerivedClass(BaseClass):
Body of derived class

Để rõ hơn về việc sử dụng kế thừa, chúng ta hãy lấy một ví dụ.

Đa giác là một hình khép kín có 3 cạnh trở lên. Chúng ta có một lớp gọi là DaGiac được định nghĩa như sau.

class DaGiac:

def __init__(self, socanh):
self.n = socanh
self.canh = [0 for i in range(socanh)]

def nhapcanh(self):
self.canh = [float(input("Bạn hãy nhập giá trị cạnh "+str(i+1)+" : ")) for i in range(self.n)]

def hienthicanh(self):
for i in range(self.n):
print("Giá trị cạnh",i+1,"là",self.canh[i])

Class DaGiac có thuộc tính n để định nghĩa số cạnh và canh để lưu giá trị mỗi cạnh. Hàm nhapcanh() lấy độ lớn các cạnh và hienthicanh() sẽ hiện thị danh sách các cạnh của đa giác.

Hình tam giác là đa giác có ba cạnh, nên ta sẽ tạo một lớp TamGiac kế thừa từ DaGiac. Class mới này sẽ thừa kế tất cả các thuộc tính sẵn có trong lớp cha nên bạn sẽ không cần khai báo lại (khả năng sử dụng lại code). TamGiac này được khai báo như sau:

class TamGiac(DaGiac):

def __init__(self):
DaGiac.__init__(self,3)

def dientich(self):
a, b, c = self.canh
# Tính nửa chu vi
s = (a + b + c) / 2
area = (s*(s-a)*(s-b)*(s-c)) ** 0.5
print('Diện tích của hình tam giác là %0.2f' %area)

Lớp TamGiac không chỉ kế thừa mà còn định nghĩa thêm một hàm mới là hàm dientich.

>>> t = TamGiac()
>>> t.nhapcanh()
Bạn hãy nhập giá trị cạnh 1 : 3
Bạn hãy nhập giá trị cạnh 2 : 5
Bạn hãy nhập giá trị cạnh 3 : 4

>>> t.hienthicanh()
Giá trị cạnh 1 là 3.0
Giá trị cạnh 2 là 5.0
Giá trị cạnh 3 là 4.0

>>> t.dientich()
Diện tích của hình tam giác là 6.00

Ta có thể thấy, các hàm nhapcanh(), hienthicanh() đều không có trong class TamGiac, nhưng chúng ta vẫn sử dụng được chúng

Overriding (Ghi đè) trong Python

Python cho phép ghi đè lên các phương thức của lớp cha. Bạn có thể thực hiện việc ghi đè phương thức của lớp cha nếu muốn có tính năng khác biệt hoặc đặc biệt trong lớp con.

Trong ví dụ trên ta thấy class TamGiac sử dụng lại hàm __init__() từ class DaGiac, nếu bạn muốn override (ghi đè) lại định nghĩa của hàm __init__() trong class cha, ta dùng hàm super().

super () .__ init __ (3) tương đương với DaGiac.__ init __ (self, 3)

Ngoài ra Python có hai hàm isinstance() và issubclass() được dùng để kiểm tra mối quan hệ của hai lớp và instance.

Hàm issubclass(classA, classB) trả về True nếu class A là lớp con của class B.

>>> issubclass(DaGiac,TamGiac)
False

>>> issubclass(TamGiac,DaGiac)
True

>>> issubclass(bool,int)
True

Hàm isinstance(obj, Class) trả về True nếu obj là một instance của lớp Class hoặc là một instance của lớp con của Class.

>>> isinstance(t,TamGiac)
True

>>> isinstance(t,DaGiac)
True

>>> isinstance(t,int)
False

>>> isinstance(t,object)
True

Xem thêm:

  • Lập trình hướng đối tượng trong Python
  • Quản lý File và thư mục trong Python
  • Tìm hiểu về Error và Exception

Bài trước: Class và Object trong Python

Bài trước: Đa kế thừa (Multiple Inheritance) trong Python