Inheritance
继承是将多个类关联起来的一种方法
当两个类相似时,可以使用继承,相似的类可能具有与通用类相同的所有属性,外加自带的特殊属性
语法: 1 2 class <name>(<base class>): <suite>
通过该语句创建的子类与其基类共享所有属性,子类可能会覆盖某些继承的属性,但未更改的保持不变
当编写子类是,只需要指出其与基类不同之处即可 ## 例
创建一个支票账户(CheckingAccount)类,作为账户(Account)类的子类
1 2 3 4 5 6 7 8 9 10 11 12 13 class CheckingAccount (Account ): """A bank account that charges for withdrawals""" withdraw_fee = 1 interest = 0.01 def withdraw (self, amount ): return Account.withdraw(self , amount + self .withdraw_fee) ch = CheckingAccount('Tom' ) print (ch.interest)ch.deposit(20 ) ch.withdraw(5 ) print (ch.balance)
此处我们在Account类的基础上修改了interest属性与withdraw方法,而其余属性与方法可以继续使用
在类上寻找属性名称
基类属性不会复制到子类中 ,确保了未经修改的属性与基类保持一致,在类中寻找名称遵循如下规则
- 如果名称为类中的属性,则返回属性值 - 若不在,在其基类中寻找该名称
面向对象设计
在进行面向对象编程时,建议遵循如下原则 -
不要重复复制粘贴已经存在的,而是利用已经存在的实现 -
已被覆盖的属性仍需要通过类来访问
如以上代码,在计算提款时最佳方式是查找实例本身上的withdraw_fee
这样,如果当前实例有一个特定的withdraw_fee,我们就使用它,否则使用Account类中的
继承与组合
继承最适合is-a 关系,如支票账户是(is
a)账户的特定类型,故适合使用继承
组合最适合has-a 关系,如一个银行具有(has
a)有一组他管理的账户,该组账户是它的一个属性,而不会继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Bank : """a bank has accounts""" def __init__ (self ): self .accounts=[] def open_account (self, holder, amount, kind = Account ): account = kind(holder) account.deposit(amount) self .accounts.append(account) return account def pay_interest (self ): for a in self .accounts: a.deposit(a.balance*a.interest) bank = Bank() john = bank.open_account('john' , 10 ) jack = bank.open_account('jack' , 5 , CheckingAccount) bank.pay_interest() print (jack.balance)print (john.balance)
多重继承
一个子类可以有多个基类
其中,这里直接调用父类account_holder时,使用super()实现了超类调用,防止破坏多重继承的调用逻辑
1 2 3 4 5 6 7 8 9 10 class SavingsAccount (Account ): deposit_fee = 2 def deposit (self, amount ): return Account.deposit(self , amount-self .deposit_fee) class GoodAccount (CheckingAccount, SavingsAccount): def __init__ (self, account_holder ): super ().__init__(account_holder) self .holder = account_holder self .balance = 1