类与类之间的关系是什么样子的?继承和组合。
- 继承是 is-a 的关系,子类 is-a 父类
- 组合是 has-a 的关系, 类B调用类A的方法,或调用模块
继承和组合的目的都是为了解决代码复用的问题。
继承和组合的使用场景是什么?或者说何种场景下选择继承或组合呢?
-
尽量不要使用多态继承。不是不可以使用继承,但要避免一个类继承了太多的类。
-
使用组合将代码打包,形成模块。这样模块可以反复使用。
-
组合优先,继承靠后。
-
不要被以上规则约束,尽量适应你团队里的习惯。
继承
继承就是子类继承父类的属性和方法,包括隐式继承,显式继承,super()
隐式继承
子类自动继承父类的方法
class Parent(object):
count = 0
def implicit(self):
print("PARENT implicit()")
Parent.count += 1
print(Parent.count)
class Child(Parent):
pass
dad = Parent()
son = Child()
dad.implicit()
son.implicit()
# 结果如下,说明 Parent()的implicit()被调用了两次。
# PARENT implicit()
# 1
# PARENT implicit()
# 2
显示继承
当子类方法名和父类方法名相同时,优先使用子类方法。
class Parent(object):
count = 0
def override(self):
print("PARENT override()")
Parent.count += 1
print(Parent.count)
class Child(Parent):
def override(self):
print("CHILD override()")
dad = Parent()
son = Child()
dad.override()
son.override()
# 结果如下,说明 Parent()的override()被调用了两次。
# PARENT override()
# 1
# CHILD override()
前后修改
在父类的版本运行之前或之后修改行为。先子类优先,使用super()调用父类。
super()解决了多重继承中寻找多个父类中的方法问题,多直接用在子类的__init()__
中。
例子1
class Child(Parent):
def __init(self, stuff):
self.stuff = stuff
super(Child, self).__init__()
例子2
class Parent(object):
count = 0
def altered(self):
print("PARENT altered()")
Parent.count += 1
print(Parent.count)
class Child(Parent):
def altered(self):
print("CHILD BEFORE PARENT altered()")
super(Child, self).altered()
print("CHILD AFTER PARENT altered()")
dad = Parent()
son = Child()
dad.altered()
son.altered()
# 结果如下,说明PARENT altered()被调用了两次。
# PARENT altered()
# 1
# CHILD BEFORE PARENT altered()
# PARENT altered()
# 2
# CHILD AFTER PARENT altered()
组合
组合也能实现继承的效果,通过将类A赋值给类B内的self,实现对类A里方法的调用。或者类B里使用模块。
class Other(object):
def override(self):
print("OTHER override()")
def implicit(self):
print("OTHER implicit()")
def altered(self):
print("OTHER altered()")
class Child(object):
def __init__(self):
self.other = Other()
def implicit(self):
self.other.implicit()
def override(self):
print("CHILD override()")
def altered(self):
print("CHILD BEFORE OTEHR altered()")
self.other.override()
print("CHILD AFTER OTHER altered()")
son = Child()
son.implicit()
son.override()
son.altered()
# 结果如下
# OTHER implicit()
# CHILD override()
# CHILD BEFORE OTEHR altered()
# OTHER override()
# CHILD AFTER OTHER altered()