Python

Class Inheritance in Python 3

GIỚI THIỆU

Tương tự như các ngôn ngữ OOP khác, chúng ta sẽ thực hiện kế thừa (Inheritance) để tái sử dụng và tránh sự dư thừa không cần thiết khi viết code.

Kế thừa chính là việc xây dựng một class mới (child class) dựa trên các class đã có (parent class). Ngoài việc thừa hưởng tất cả các thuộc tính của parent class, các child class còn có thêm các thuộc tính mới mà parent class không có.


PARENT CLASS

Việc tạo một parent class hoàn toàn giống như tạo một class thông thường, trong example 1 chúng ta sẽ tạo một class tên là Animal:

Example 1 – Parent class

class Animal:
    def __init__(self, name, age, color):
        self.name = name
        self.age = age
        self.color = color

    def eat(self):
        print("I'm eating.")

    def sleep(self):
        print("I'm sleeping.")

CHILD CLASS

Trong example 2, chúng ta sẽ tạo hai child classes là Dog và Cat.
Example 2 – Child classes

class Dog(Animal):
    pass

class Cat(Animal):
    def miaow():
        print("Miaow-miaowww.")

Các child class Dog và Cat được thừa hưởng tất cả các thuộc tính từ parent class Animal.
Trong example 3, chúng ta sẽ gọi và sử dụng các class Dog và Cat
Example 3 – Using child classes

dog = Dog("Ben", 3, "yellow")
cat = Cat("Si", 2, "black")

dog.eat()
cat.sleep()
cat.miaow()

Output:
I’m eating.
I’m sleeping.
Miaow-miaowww.

Trong example 3 ta thấy rằng, các child class thừa kế parent class Animal bằng cách khai báo ChildClass(ParentClass), các tham số của parent class Animal (bao gồm name, age, color) sẽ được truyền vào thông qua class Dog và Cat; class Cat có thêm method miaow mà không có ở parent class Animal.


OVERRIDDING PARENT METHODS

Ở example 2 và 3, các child classes được thừa hưởng toàn bộ các thuộc tính của parent class và có thêm một vài thuộc tính mới. Tuy nhiên nếu muốn thay đổi các thuộc tính thừa hưởng từ parent, chúng ta cần overridding chúng.

Example 4 – Overriding parent methods

class Dog(Animal):
    def eat(self):
        print("Dog is eating.")

class Cat(Animal):
    def sleep(self):
        print("Cat is sleeping.")

dog = Dog("ben", 4, "yellow")
cat = Cat("si", 2, "black")

print(dog.name+':')
dog.eat()
dog.sleep()
print(cat.name+':')
cat.eat()
cat.sleep()
cat.miaow()

Output:
Ben:
Dog is eating.
I’m sleeping.
Si:
I’m eating.
Cat is sleeping.
Miaow-miaowwww.

Trong example 4, chúng ta đã chỉnh sửa method eat() của class Dog và method sleep() của class Cat, còn method eat() của Cat và method sleep() của Dog được giữa nguyên so với parent class. Nếu muốn chúng ta có thể chỉnh sửa method __init__() của các child class.


THE SUPER() BUILT-IN FUNCTION

Ở phần trước chúng ta đã thực hiện Overridding để chỉnh sửa các method của các Child Class cho phù hợp các yêu cầu mới, tuy nhiên khi cần tận dụng một số thuộc tính của các method đang được overridding, chúng ta buộc phải gõ lại (copy lại) chúng từ parent class. Để giải quyết vấn đề này chúng ta sử dụng built-in function super() để gọi các thuộc tính của Parent Class vào trong Child Class.

Example 5 – Overridding without super()

class Dog(Animal):
    def __init__(self, name, age, color, type):
        self.name = name
        self.age = age
        self.color = color
        # this is a new variable
        self.type = type

    def eat(self):
        print("I'm eating.")
        # this is a new message
        print("I like bone!")

dog = Dog("Ben", 4, "yellow", "Pug")
print(dog.name + ' ' + dog.type + ':')
dog.eat()
dog.sleep()

Output:
Ben Pug:
I’m eating.
I like bone!
I’m sleeping.

Example 6 – Overridding with super()

class Dog(Animal):
    def __init__(self, name, age, color, type):
        super().__init__(name, age, color)
        # this is a new variable
        self.type = type

    def eat(self):
        super().eat()
        # this is a new message
        print("I like bone!")

dog = Dog("Ben", 4, "yellow", "Pug")
print(dog.name + ' ' + dog.type + ':')
dog.eat()
dog.sleep()

Output:
Ben Pug:
I’m eating.
I like bone!
I’m sleeping.

Như vậy, với built-in function super() chúng ta có thể tái sử dụng các method của Parent Class trong khi vẫn có thể chỉnh sửa chúng cho phù hợp với yêu cầu mới.


MULTIPLE INHERITANCE

Multiple Inheritance là trường hợp khi một childclass thừa hưởng các thuộc tính từ nhiều parentclasses.

Python 3 áp dụng MRO (Method Resolution Order) để xác định thứ tự kế thừa trong Multiple Inheritance.

Cùng xem xét ví dụ dưới đây để hiểu rõ hơn về MRO.

Example 7: Multiple Inheritance with MRO

class A:
	def say(self):
		print("Hi, I'm A")

class B(A):
	def say(self):
		print("Hi, I'm B.")
		super().say()

class C(A):
	def say(self):
		print("Hi, I'm C.")
		super().say()

class D(B, C):
	pass

d = D()
d.say()

print(D.__mro__)
print(D.__bases__)
print(D.__name__)

Output:
Hi, I’m B
Hi, I’m C
Hi, I’m A
(<class ‘__main__.D’>, <class ‘__main__.B’>, <class ‘__main__.C’>, <class ‘__main__.A’>, <class ‘object’>)
(<class ‘__main__.B’>, <class ‘__main__.C’>)
D

Với kết quả nhận được chúng ta thấy rằng, class D thừa kế từ class B,class B thừa kế từ class C, class C thừa kế từ class A và class A thừa kế từ class object. Việc kế thừa như vậy giúp tránh khỏi The Diamond Problem.

Tiếp theo chúng ta sẽ tìm hiểu một ví dụ về ứng dụng của Multiple Inheritance.

Example 8: Ordered Counter

from collections import Counter, OrderedDict

class OrderedCounter(Counter, OrderedDict):
	pass 

print(OrderedCounter("codelungtung"))

Output:
OrderedCounter({‘u’: 2, ‘n’: 2, ‘g’: 2, ‘c’: 1, ‘o’: 1, ‘d’: 1, ‘e’: 1, ‘l’: 1, ‘t’: 1})


KẾT LUẬN

Qua bài viết này chúng ta đã tìm hiểu về sự kế thừa trong OOP và cách kế thừa các class trong Python 3. Cảm ơn các bạn đã theo dõi bài viết của mình.

Thân ái và quyết thắng.

Reference:
[1] Understanding Class Inheritance in Python 3.
[2] Inheritance – Python Course.
[3] Multiple Inheritance in Python 3.
[4] How to create an Ordered Counter class in Python.
[5] Python’s super().

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s