Kế thừa Python là khi một lớp con sử dụng mã từ một lớp khác. Kế thừa là một tính năng cần thiết trong các ngôn ngữ hướng đối tượng như Python, giúp mã hóa dễ dàng và hiệu quả hơn.
Python là một ngôn ngữ hướng đối tượng, có nghĩa là nó hỗ trợ tạo các khối mã có thể tái sử dụng để giúp tạo mã hiệu quả hơn. Một trong những cách mà điều này xảy ra là thông qua kế thừa, trong đó một lớp con có thể sử dụng mã từ một lớp khác.
Ví dụ:bạn có thể có một lớp lưu trữ “tài khoản ngân hàng” và muốn tạo một lớp con lưu trữ “tài khoản ngân hàng vàng” có thể tham chiếu các thuộc tính trong lớp “tài khoản ngân hàng” hiện có.
Trong hướng dẫn này, chúng ta sẽ phân tích những điều cơ bản về kế thừa trong Python. Chúng ta cũng sẽ thảo luận về cách hoạt động của các lớp Python cha và con cũng như cách ghi đè các thuộc tính và phương thức khi bạn đang làm việc với các đối tượng lớp.
Kế thừa Python
Kế thừa là một thuật ngữ được sử dụng để mô tả một lớp Python trong một lớp khác. Các lớp được gọi là subclasses
hoặc subclasses
có thể kế thừa các giá trị từ parent classes
, tương tự như cách con cái thừa hưởng các đặc điểm từ cha mẹ của chúng trong thế giới thực.
Kế thừa hữu ích vì nó cho phép chúng ta tạo subclasses
có cùng kiểu giá trị với lớp cha mà không cần phải khai báo những kiểu đó nhiều lần.
Lớp dành cho cha mẹ
Các lớp cha (còn được gọi là base classes
tạo cấu trúc chủ mà các lớp con có thể truy cập. Chúng ta có thể tạo nhiều lớp con mà không cần phải khai báo lại cùng một tập các giá trị chung mà các phương thức của lớp dẫn xuất từ lớp cha.
Hãy sử dụng một ví dụ để minh họa cách điều này sẽ hoạt động trong thực tế. Giả sử rằng chúng tôi có một chương trình hoạt động với hai loại tài khoản ngân hàng khác nhau:tài khoản chính và tài khoản con.
81% người tham gia cho biết họ cảm thấy tự tin hơn về triển vọng công việc công nghệ của mình sau khi tham gia một cuộc thi đào tạo. Kết hợp với bootcamp ngay hôm nay.
Sinh viên tốt nghiệp bootcamp trung bình đã dành ít hơn sáu tháng để chuyển đổi nghề nghiệp, từ khi bắt đầu bootcamp đến khi tìm được công việc đầu tiên của họ.
Cả hai tài khoản này đều là tài khoản ngân hàng nên chúng sẽ có giá trị tương tự nhau. Nhưng mỗi tài khoản này có thể yêu cầu thông tin riêng của chúng. Ví dụ:tài khoản của cha mẹ có thể hỗ trợ thấu chi, trong khi tài khoản của con chỉ có thể hoạt động với số dư của họ.
Vì vậy, nếu chúng tôi muốn tạo một chương trình với những giá trị này, trước tiên chúng tôi sẽ xác định một lớp cho tài khoản ngân hàng của mình (một lớp cha), sau đó tạo các lớp con cho hai loại tài khoản ngân hàng — cha và con — mà chúng tôi muốn hỗ trợ.
Dưới đây là một ví dụ về việc khai báo lớp cha cho tài khoản ngân hàng:
class BankAccount: def __init__(self, forename, surname, balance): self.forename = forename self.surname = surname self.balance = balance
Chúng tôi đã tạo lớp BankAccount
trong đó lưu trữ ba giá trị:họ, tên và số dư. Chúng ta cũng có thể thêm các phương thức vào lớp của mình, như sau:
class BankAccount: def __init__(self, forename, surname, balance): self.forename = forename self.surname = surname self.balance = balance def getDetails(self): print("Forename: ", self.forename) print("Surname: ", self.surname) def getBalance(self): print("Balance: $ ", self.balance)
Lớp của chúng ta hiện lưu trữ ba giá trị, cũng như hai phương thức mới:chi tiết và số dư. details
phương pháp này có thể được sử dụng để tìm ra họ và tên của chủ tài khoản của chúng tôi cũng như balance
phương pháp này sẽ trả lại số dư của chủ tài khoản.
Mọi phương thức và biến mà chúng tôi khai báo trong BankAccount
của chúng tôi sẽ có thể truy cập lớp học trong lớp con của chúng tôi.
Để minh họa lớp học của chúng ta trong thực tế, hãy tạo một tài khoản ngân hàng mẫu. Chúng tôi có thể làm như vậy bằng cách sử dụng mã sau:
account = BankAccount("John", "Appleseed", 100)
Thao tác này sẽ tạo tài khoản cho John Appleseed
trong đó có $ 100. Bây giờ chúng ta đã sẵn sàng tài khoản của mình, chúng ta có thể bắt đầu tham chiếu nó giống như chúng ta làm với bất kỳ lớp nào khác. Đây là một ví dụ về việc chúng tôi chạy getBalance()
trong tài khoản ngân hàng của chúng tôi để biết chúng tôi có bao nhiêu tiền:
print(account.getBalance())
Chương trình của chúng tôi trả về như sau:
Balance: $ 100
Lớp học dành cho trẻ em
Trong ví dụ trên, chúng tôi đã khai báo một lớp cha lưu trữ các tài khoản ngân hàng. Nhưng nếu chúng ta muốn lưu trữ thông tin về một loại tài khoản cụ thể như tài khoản của trẻ em dưới 18 tuổi thì sao? Đó là nơi mà các lớp học trẻ em đến.
Các lớp con, hoặc lớp con, kế thừa các giá trị từ lớp cha. Điều này có nghĩa là mỗi lớp con sẽ có thể tham chiếu đến các phương thức và biến mà chúng ta khai báo trong lớp cha của mình.
Vì vậy, giả sử chúng tôi muốn tạo một lớp con cho ChildBankAccount
. Tài khoản này phải có thể trả lại thông tin tài khoản ngân hàng của người dùng — tên và số dư của họ — và cũng phải có một giá trị mới được gọi là restricted
. Giá trị này sẽ được lưu trữ trong tài khoản của trẻ vì trẻ dưới 18 tuổi và không đủ điều kiện để có tài khoản ngân hàng đầy đủ.
Để tạo một lớp con, chúng ta có thể sử dụng đoạn mã sau:
class ChildBankAccount(BankAccount):
ChildBankAccount
lớp trở thành con của BankAccount
lớp vì BankAccount
được đặt trong dấu ngoặc đơn. Nếu chúng ta muốn lớp con của mình có cùng giá trị với lớp cha— BankAccount
—Chúng ta có thể sử dụng pass
từ khóa như thế này:
class ChildBankAccount(BankAccount): pass
Nhưng như chúng ta đã thảo luận trước đó, tài khoản con của chúng ta sẽ cần lưu trữ một giá trị đặc biệt:một biến cho biết rằng tài khoản của người dùng bị hạn chế.
Để đạt được mục tiêu này, chúng tôi sẽ thêm một giá trị mới có tên là restricted
đến lớp con của chúng tôi. Chúng tôi có thể thực hiện việc này bằng đoạn mã sau:
class ChildBankAccount(BankAccount): def __init__(self, forename, surname, balance, restricted=True): self.forename = forename self.surname = surname self.balance = balance self.restricted = restricted def isRestricted(self): print("This account is restricted as the user is under 18.")
Bây giờ, hãy chia nhỏ mã của chúng ta.
Trong đoạn mã trên, chúng tôi tuyên bố rằng chúng tôi muốn Tài khoản ChildBankAccount của chúng tôi giữ bốn giá trị:tên, họ, số dư và bị giới hạn.
Ba giá trị đầu tiên — họ, tên và số dư — giống với giá trị lớp mẹ của chúng tôi nhưng restricted
là mới, và nó là độc quyền cho lớp con của chúng tôi. Theo mặc định, restricted
được đặt thành True
.
Vì vậy, nếu chúng tôi tạo một BankAccount
chuẩn (không phải là ChildBankAccount
), chúng tôi sẽ không thể truy cập vào restricted
giá trị. Tương tự, chúng tôi sẽ không thể truy cập vào isRestricted
trừ khi chúng tôi tạo ChildBankAccount
.
Đây là ví dụ về việc chúng tôi tạo ChildBankAccount
và sử dụng getBalance()
và isResticted()
phương pháp để tìm hiểu thêm về lớp học của chúng tôi:
child_account = ChildBankAccount("Bill", "Appleseed", 100) print(child_account.getBalance()) print(child_account.isRestricted())
Mã của chúng tôi trả về như sau:
Balance: $ 100 This account is restricted as the user is under 18.
Như bạn có thể thấy, chương trình của chúng tôi trước tiên xác định một ChildBankAccount
mới cho Bill Appleseed
, người có tài khoản $ 100. Sau đó, chương trình của chúng tôi thực thi getBalance()
trong lớp của chúng tôi, trả về số dư của người dùng. getBalance()
được khai báo trong lớp mẹ của chúng tôi, BankAccount
, nhưng có thể truy cập được vào ChildBankAccount
thông qua kế thừa .
Chương trình của chúng tôi cũng thực thi isRestricted()
, trong đó nói rằng tài khoản của trẻ bị hạn chế vì chúng dưới 18 tuổi. Lớp này được khai báo trong ChildBankAccount
, tuy nhiên, điều đó có nghĩa là nó không thể truy cập được vào BankAccount
lớp mẹ của chúng tôi . Nếu chúng tôi muốn tạo một BankAccount
bị hạn chế , chúng tôi sẽ cần thay đổi lớp cha.
Xác định lại các phương thức gốc
Trong ví dụ trên, chúng tôi đã khai báo một lớp cha có tên là BankAccount
nơi lưu trữ thông tin cho các tài khoản ngân hàng. Chúng tôi cũng đã tạo một lớp con có tên là ChildBankAccount
lưu trữ thông tin cho chủ tài khoản dưới 18 tuổi. Lớp này kế thừa các phương thức từ BankAccount
và cũng đã tạo isRestricted()
phương pháp.
Nhưng điều gì sẽ xảy ra nếu chúng ta muốn sửa đổi một phương thức của lớp cha hiện có? Giả sử chúng tôi muốn BankAccount
của mình số dư để trả lại một tin nhắn với số dư của họ và một tin nhắn cho biết You are eligible for an overdraft
, nhưng chúng tôi không muốn điều này xuất hiện cho ChildBankAccount
chủ sở hữu.
Để thực hiện việc này, chúng ta cần ghi đè phương thức gốc của mình.
Đây là mã cho phương thức gốc đã sửa đổi của chúng tôi, BankAccount
, hiện sẽ in một thông báo cho các chủ tài khoản để nói rằng họ đủ điều kiện để được thấu chi khi họ kiểm tra số dư của mình:
class BankAccount: def __init__(self, forename, surname, balance): self.forename = forename self.surname = surname self.balance = balance def getDetails(self): print("Forename: ", self.forename) print("Surname: ", self.surname) def getBalance(self): print("Balance: $ ", self.balance) print("You are eligible for an overdraft.")
Bây giờ, nếu chúng ta tạo một BankAccount
mới cho John Appleseed
và in ra số dư của anh ấy, chúng tôi sẽ thấy một thông báo cho biết You are eligible for an overdraft
. Dưới đây là một ví dụ về việc chúng tôi khai báo một tài khoản mới và kiểm tra số dư của nó:
account = BankAccount("John", "Appleseed", 100) print(account.getBalance())
Mã của chúng tôi trả về như sau:
Balance: $ 100 You are eligible for an overdraft.
Nhưng thay đổi này cũng có nghĩa là ChildBankAccount
của chúng tôi , kế thừa các giá trị của nó từ BankAccount
, cũng sẽ thấy thông báo. Đây là ví dụ về việc chúng tôi tạo ChildBankAccount
và kiểm tra số dư của nó bây giờ là BankAccount
của chúng tôi lớp cha đã thay đổi:
child_account = ChildBankAccount("Bill", "Appleseed", 100) print(child_account.getBalance())
Mã của chúng tôi trả về:
Balance: $ 100 You are eligible for an overdraft.
Bởi vì trẻ em nói chung không được phép thấu chi, chúng tôi sẽ cần thực hiện thay đổi đối với mã của mình. Bây giờ, để làm như vậy, chúng tôi phải sửa đổi ChildBankAccount
của mình lớp và khai báo một getBalance()
mới chức năng.
Đây là mã cho ChildBankAccount
của chúng tôi từ bên trên:
class ChildBankAccount(BankAccount): def __init__(self, forename, surname, balance, restricted=True): self.forename = forename self.surname = surname self.balance = balance self.restricted = restricted def isRestricted(self): print("This account is restricted as the user is under 18.")
Chúng ta cần thay đổi mã này để thêm một hàm mới:getBalance()
. Hàm này sẽ hoạt động giống như hàm mà chúng ta đã khai báo trong lớp cha, nhưng nó sẽ không bao gồm thông báo về khoản thấu chi. Đây là mã mà chúng tôi sẽ thêm để khai báo chức năng mới của mình:
… def getBalance(self): print("Balance: $ ", self.balance)
Bây giờ chúng ta hãy thử lấy lại số dư của con chúng ta:
child_account = ChildBankAccount("Bill", "Appleseed", 100) print(child_account.getBalance())
Mã của chúng tôi trả về như sau:
Balance: $ 100
Trong ví dụ trên, chúng tôi đã ghi đè getBalance()
trong ChildBankAccount
lớp trẻ em. getBalance()
mới của chúng tôi phương thức cho ChildBankAccount
chỉ hiển thị số dư của người dùng. Nhưng trong BankAccount
của chúng tôi lớp, getBalance()
phương thức hiển thị cả số dư của người dùng và thông báo You are eligible for an overdraft
.
Ghi đè các phương thức cha có thể hữu ích khi bạn có nhiều phương thức con có thể sử dụng các phương pháp tương tự với phương thức cha mẹ của chúng, nhưng yêu cầu thực hiện các thay đổi cụ thể của riêng chúng. Giống như trong trường hợp trên, chúng tôi muốn tài khoản ngân hàng mẹ của mình nhìn thấy thông báo thấu chi, nhưng không phải tài khoản ngân hàng con của chúng tôi, vì vậy chúng tôi ghi đè phương thức mẹ của mình trong ChildBankAccount
.
Kết luận
Kế thừa được sử dụng trong lập trình hướng đối tượng để giúp bạn tạo các lớp con có thể lưu trữ các giá trị đã được khai báo trong một lớp cha. Điều này hữu ích khi bạn đang tạo các lớp tương tự sẽ lưu trữ các giá trị tương tự vì bạn có thể sử dụng kế thừa để tạo các lớp đó mà không cần lặp lại mã của bạn nhiều lần.
Trong hướng dẫn này, chúng tôi đã khám phá vai trò của kế thừa trong Python. Chúng tôi cũng đã thảo luận về cách hoạt động của kế thừa và các lớp cha và con, sau đó chúng tôi khám phá cách ghi đè các phương thức cha. Bây giờ, bạn đã sẵn sàng làm việc với các lớp và kế thừa như một chuyên gia Python!