Thừa kế trong Lập trình Hướng đối tượng Python

Thừa kế là một cơ chế quan trọng trong lập trình hướng đối tượng, cho phép tái sử dụng mã nguồn và thiết kế. Khi thiết kế một lớp mới, nếu có thể kế thừa từ một lớp đã được thiết kế tốt, chúng ta sẽ giảm đáng kể lượng công việc phát triển cần thực hiện.

  1. Cú pháp kế thừa lớp:

class TênLớpCon(TênLớcCha): # Tên lớp cha được đặt trong ngoặc đơn

Thành viên của lớp con

Trong mối quan hệ kế thừa, lớp đã có sẵn và được thiết kế tốt được gọi là lớp cha hoặc lớp cơ sở, lớp mới được thiết kế được gọi là lớp con hoặc lớp dẫn xuất. Lớp con có thể kế thừa các thành viên công khai của lớp cha, nhưng không thể kế thừa các thành viên riêng tư.

Một số đặc điểm của kế thừa trong Python:

  1. Đặc điểm của kế thừa lớp:

A. Trong kế thừa, hàm khởi tạo (init() method) của lớp cha sẽ không được tự động gọi, nó cần được gọi một cách rõ ràng trong hàm khởi tạo của lớp con.

B. Khi cần gọi phương thức của lớp cha trong lớp con, có thể sử dụng cú pháp "TênLớpCha.tênPhương thức()". Khác với việc gọi hàm thông thường trong lớp không cần tham số self, việc gọi phương thức của lớp cha cần có cả tham số self. Hoặc có thể sử dụng hàm super() tích hợp sẵn để đạt được mục đích này.

C. Python luôn tìm kiếm phương thức của loại tương ứng trước. Nếu không tìm thấy phương thức trong lớp con, nó mới bắt đầu tìm lần lượt trong các lớp cha (tìm trong lớp hiện tại trước, không tìm mới sang lớp cha).

  1. Ví dụ về tái cấu trúc lớp:

# Tác giả: Minh Anh
# Giả sử hệ thống đăng nhập có nhiều loại người dùng khác nhau, mỗi loại có chức năng riêng
# nhưng có chung một số chức năng. Ví dụ:
# user: đăng nhập, xem, thêm máy chủ, thêm mật khẩu, tải gói phần mềm
# admin: đăng nhập, xem, thêm tài khoản, xóa tài khoản, khóa tài khoản, truy cập API.
# superadmin: đăng nhập, xem, thêm tài khoản, xóa tài khoản, khóa tài khoản, sửa miền, sửa cây sản phẩm.

# Chúng ta có thể sử dụng phương pháp hướng đối tượng để thực hiện:
# Định nghĩa lớp: lớp1: user
#                lớp2: admin
#                lớp3: superadmin
# Ngoài ra, có thể trừu tượng hóa các phương thức chung làm lớp cha, để các lớp con sử dụng
# lớp4: chung: định nghĩa các phương thức chung "đăng nhập, xem".
# lớp5: quanly_tai khoan: định nghĩa các phương thức quản lý tài khoản "thêm, xóa, khóa tài khoản".

class chung:
    def __init__(self, ten):
        self.ten = ten

    def dang_nhap(self):
        print("%s đang đăng nhập..."%self.ten)

    def xem_thong_tin(self):
        print("%s đang xem thông tin..."%self.ten)

class quanly_taikhoan:
    def __init__(self, ten):
        self.ten = ten

    def them_taikhoan(self):
        print("%s đang thêm tài khoản..."%self.ten)

    def xoa_taikhoan(self):
        print("%s đang xóa tài khoản..."%self.ten)

    def khoa_taikhoan(self):
        print("%s đang khóa tài khoản..."%self.ten)

class user(chung):   # Kế thừa lớp chung
    '''
    Lớp này thực hiện các chức năng của người dùng user, kế thừa phương thức từ lớp cha
    '''
    def __init__(self, ten, ip):   # Khởi tạo lớp con, cần định nghĩa tham số của lớp cha
        chung.__init__(self, ten)    # Gọi lại phương thức của lớp cha
        self.ip = ip

    def them_maychu(self):
        print("%s thêm máy chủ %s"%(self.ten, self.ip))

    def them_matkhau(self):
        print("Thêm mật khẩu")

    def tai_goi(self):
        print("Đang tải gói phần mềm...")

        # Nếu cần thêm chức năng mới cho phương thức của lớp cha, 
        # ví dụ khi đăng nhập cần kiểm tra bản thân là ai, cần tái định nghĩa phương thức

    def dang_nhap(self):
        chung.dang_nhap(self)  # Gọi lại phương thức lớp cha và truyền tham số self
        print("Xác nhận người dùng...")

class admin(chung):  # Định nghĩa lớp admin, kế thừa lớp chung

    def truy_cap_api(self, ten):
        print("%s truy cập API của hệ thống..."%ten)


#user1 = user("minh_anh")
#user1.xem_thong_tin()  # Gọi phương thức của lớp cha
#user1.them_maychu("minh_anh","192.168.42.111")  # Gọi phương thức của lớp con
#user1.dang_nhap()  # Khi chưa tái định nghĩa phương thức của lớp cha, 
                    # phương thức được gọi là phương thức của lớp con
                    # Nếu cần thêm chức năng mới thì phải tái định nghĩa phương thức lớp cha
#user1.dang_nhap()  # Sau khi tái định nghĩa, sẽ hiển thị cả phương thức của lớp cha và lớp con

admin1 = admin("admin")  # Tạo đối tượng lớp admin
admin1.truy_cap_api("admin") # Gọi phương thức truy_cap_api
admin1.xem_thong_tin()  # Gọi phương thức xem_thong_tin

# Nếu cần thêm chức năng cho user, ví dụ khi đăng nhập kiểm tra máy chủ có tồn tại (cần thêm tham số),
# trong khi admin không cần chức năng này. Làm thế nào?
# Nếu sửa lớp chung, tất cả người dùng đều bị ảnh hưởng, lúc này cần tái định nghĩa phương thức lớp cha

user1 = user("user1","192.168.42.111")
user1.xem_thong_tin()
user1.them_maychu()
  1. Kế thừa đa lớp

# Tác giả: Minh Anh
# Giả sử hệ thống đăng nhập có nhiều loại người dùng khác nhau, mỗi loại có chức năng riêng
# nhưng có chung một số chức năng. Ví dụ:
# user: đăng nhập, xem, thêm máy chủ, thêm mật khẩu, tải gói phần mềm
# admin: đăng nhập, xem, thêm tài khoản, xóa tài khoản, khóa tài khoản, truy cập API.
# superadmin: đăng nhập, xem, thêm tài khoản, xóa tài khoản, khóa tài khoản, sửa miền, sửa cây sản phẩm.

# Chúng ta có thể sử dụng phương pháp hướng đối tượng để thực hiện:
# Định nghĩa lớp: lớp1: user
#                lớp2: admin
#                lớp3: superadmin
# Ngoài ra, có thể trừu tượng hóa các phương thức chung làm lớp cha, để các lớp con sử dụng
# lớp4: chung: định nghĩa các phương thức chung "đăng nhập, xem".
# lớp5: quanly_taikhoan: định nghĩa các phương thức quản lý tài khoản "thêm, xóa, khóa tài khoản".

# Lớp admin và superadmin đều có thể kế thừa lớp chung và lớp quanly_taikhoan, sử dụng kế thừa đa lớp

class chung:
    def __init__(self, ten):
        self.ten = ten

    def dang_nhap(self):
        print("%s đang đăng nhập..."%self.ten)

    def xem_thong_tin(self):
        print("%s đang xem thông tin..."%self.ten)


class quanly_taikhoan:
    def __init__(self, ten, ma_nd):
        self.ten = ten
        self.ma_nd = ma_nd

    def them_taikhoan(self):
        print("%s đang thêm tài khoản...%s"%(self.ten, self.ma_nd))

    def xoa_taikhoan(self):
        print("%s đang xóa tài khoản..."%self.ten)

    def khoa_taikhoan(self):
        print("%s đang khóa tài khoản..."%self.ten)

class user(chung):   # Kế thừa lớp chung
    '''
    Lớp này thực hiện các chức năng của người dùng user, kế thừa phương thức từ lớp cha
    '''
    def __init__(self, ten, ip):   # Khởi tạo lớp con, cần định nghĩa tham số của lớp cha
        chung.__init__(self, ten)    # Gọi lại phương thức của lớp cha
        self.ip = ip

    def them_maychu(self):
        print("%s thêm máy chủ %s"%(self.ten, self.ip))

    def them_matkhau(self):
        print("Thêm mật khẩu")

    def tai_goi(self):
        print("Đang tải gói phần mềm...")

        # Nếu cần thêm chức năng mới cho phương thức của lớp cha, 
        # ví dụ khi đăng nhập cần kiểm tra bản thân là ai, cần tái định nghĩa phương thức

    def dang_nhap(self):
        chung.dang_nhap(self)  # Gọi lại phương thức lớp cha và truyền tham số self
        print("Xác nhận người dùng...")

#user1 = user("user1","192.168.42.111")
#user1.xem_thong_tin()
#user1.them_maychu()

class superadmin(chung, quanly_taikhoan):
    '''
    Lớp này thực hiện chức năng của superadmin, kế thừa lớp chung và lớp quanly_taikhoan
    '''
    def __init__(self, ten, ma_nd, vung):  # Khởi tạo lớp superadmin, cần thêm tất cả tham số của lớp cha
        self.vung = vung
        chung.__init__(self, ten)  # Gọi lại phương thức của lớp cha chung
        quanly_taikhoan.__init__(self, ten, ma_nd)  # Gọi lại phương thức của lớp cha quanly_taikhoan

    def sua_vung(self):
        print("Sửa vùng %s"%self.vung)

superadmin1 = superadmin("superadmin", 11, "hanoi")
superadmin1.xem_thong_tin()
superadmin1.them_taikhoan()
superadmin1.sua_vung()
  1. Kế thừa trong lớp cổ điển và lớp mới
# Tác giả: Minh Anh
# Giả sử hệ thống đăng nhập có nhiều loại người dùng khác nhau, mỗi loại có chức năng riêng
# nhưng có chung một số chức năng. Ví dụ:
# user: đăng nhập, xem, thêm máy chủ, thêm mật khẩu, tải gói phần mềm
# admin: đăng nhập, xem, thêm tài khoản, xóa tài khoản, khóa tài khoản, truy cập API.
# superadmin: đăng nhập, xem, thêm tài khoản, xóa tài khoản, khóa tài khoản, sửa miền, sửa cây sản phẩm.

# Chúng ta có thể sử dụng phương pháp hướng đối tượng để thực hiện:
# Định nghĩa lớp: lớp1: user
#                lớp2: admin
#                lớp3: superadmin
# Ngoài ra, có thể trừu tượng hóa các phương thức chung làm lớp cha, để các lớp con sử dụng
# lớp4: chung: định nghĩa các phương thức chung "đăng nhập, xem".
# lớp5: quanly_taikhoan: định nghĩa các phương thức quản lý tài khoản "thêm, xóa, khóa tài khoản".

# Lớp admin và superadmin đều có thể kế thừa lớp chung và lớp quanly_taikhoan, sử dụng kế thừa đa lớp

#class chung:  # Lớp cổ điển
class chung(object):  # Lớp mới
    def __init__(self, n1):
        pass

    def dang_nhap(self):
        print("%s đang đăng nhập..."%self.ten)

    def xem_thong_tin(self):
        print("%s đang xem thông tin..."%self.ten)


#class quanly_taikhoan:  # Lớp cổ điển
class quanly_taikhoan(object): # Lớp mới

    def __init__(self, ten, ma_nd):
        self.ten = ten
        self.ma_nd = ma_nd

    def them_taikhoan(self):
        print("%s đang thêm tài khoản...%s"%(self.ten, self.ma_nd))

    def xoa_taikhoan(self, obj):
        print("%s đang xóa tài khoản...%s"%(self.ten, obj.ten))

    def khoa_taikhoan(self):
        print("%s đang khóa tài khoản..."%self.ten)

class user(chung):   # Kế thừa lớp chung
    '''
    Lớp này thực hiện các chức năng của người dùng user, kế thừa phương thức từ lớp cha
    '''
    def __init__(self, ten, ip):   # Khởi tạo lớp con, cần định nghĩa tham số của lớp cha
        chung.__init__(self, ten)    # Gọi lại phương thức của lớp cha
        self.ip = ip

    def them_maychu(self):
        print("%s thêm máy chủ %s"%(self.ten, self.ip))

    def them_matkhau(self):
        print("Thêm mật khẩu")

    def tai_goi(self):
        print("Đang tải gói phần mềm...")

        # Nếu cần thêm chức năng mới cho phương thức của lớp cha, 
        # ví dụ khi đăng nhập cần kiểm tra bản thân là ai, cần tái định nghĩa phương thức

    def dang_nhap(self):
        chung.dang_nhap(self)  # Gọi lại phương thức lớp cha và truyền tham số self
        print("Xác nhận người dùng...")

class superadmin(chung, quanly_taikhoan):  # Thứ tự thực hiện lớp từ trái sang phải
    '''
    Lớp này thực hiện chức năng của superadmin, kế thừa lớp chung và lớp quanly_taikhoan
    '''
    def __init__(self, ten, ma_nd, vung):  # Khởi tạo lớp superadmin, cần thêm tất cả tham số của lớp cha
        self.vung = vung
        chung.__init__(self, ten)  # Gọi lại phương thức của lớp cha chung
        quanly_taikhoan.__init__(self, ten, ma_nd)  # Gọi lại phương thức của lớp cha quanly_taikhoan

    def sua_vung(self):
        print("Sửa vùng %s"%self.vung)

superadmin1 = superadmin("superadmin", 11, "hanoi")  # Tham số của lớp sẽ được tìm trong toàn bộ chuỗi kế thừa
superadmin1.xem_thong_tin()
superadmin1.them_taikhoan()
superadmin1.sua_vung()




Quan hệ kế thừa giữa lớp cổ điển và lớp mới:

Kế thừa trong lớp cổ điển và lớp mới có sự khác biệt về thứ tự kế thừa của lớp con và hàm khởi tạo của lớp con:

Trong Python 2, lớp cổ điển sử dụng kế thừa theo chiều sâu, lớp mới sử dụng kế thừa theo chiều rộng.

Trong Python 3, cả lớp cổ điển và lớp mới đều sử dụng kế thừa theo chiều rộng.

Thực tế, trong Python 3 đã không còn khái niệm lớp cổ điển, hệ thống mặc định là lớp mới:

# Tác giả: Minh Anh

# Trong quá trình kế thừa lớp cổ điển, thứ tự kế thừa hàm khởi tạo là "kế thừa theo chiều rộng"
# Ví dụ sau: D-->B--->C--->A

class A(object):
    def __init__(self):
    #def test_a(self):
        print("TRONG LỚP A")

class B(A):
    #def __init__(self):
    #def test_b(self):
        print("TRONG LỚP B")

class C(A):
    #def __init__(self):
    #def test_c(self):
        print("TRONG LỚP C")

class D(B,C):
    #def __init__(self):
    #def test_d(self):
        print("TRONG LỚP D")

d1 = D()
#d1.test_d()

Thẻ: python Kế thừa Lập trình hướng đối tượng oop đa kế thừa

Đăng vào ngày 3 tháng 7 lúc 23:01