Inheritance
继承是将多个类关联起来的一种方法
当两个类相似时,可以使用继承,相似的类可能具有与通用类相同的所有属性,外加自带的特殊属性
语法: 1
2class <name>(<base class>):
<suite>
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) # 存入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