习题 44:继承与合成
继承就是用来表明一个类的大部分或全部功能都是从一个父类中获得的。
父类和之类有三种交互方式:
子类上的动作完全等同于父类上的动作;
子类上的动作完全覆盖了父类上的动作;
子类上的动作部分替换了父类上的动作。
隐式继承:当你在父类里定义了一个函数,但没有在子类中定义。
class Parent:
def implicit(self):
print("Parent implicit()")
class Child(Parent):
pass
dad = Parent()
son = Child()
dad.implicit()
son.implicit()
pass 是在 Python 中创建空代码块的方法
如果将函数放到基类中,那么所有的子类将会自动获得这些函数的功能。
显示覆盖:有时候需要让子类里的函数有一个不同的行为,这种情况下需要覆盖父类中的函数,从而实现它的新功能,只要在子类中定义一个相同名称的函数就可以了。
class Parent:
def override(self):
print("Parent override()")
class Child(Parent):
def override(self):
print("Child override")
dad = Parent()
son = Child()
dad.override()
son.override()
在运行前或运行后替换:是覆盖的特例,在父类中定义的内容运行之前或者之后再修改行为,需要用 Python 的内置函数 super 来调用父类里的版本。
class Parent:
def altered(self):
print("Parent altered()")
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()
三种方式组合使用
class Parent:
def override(self):
print("Parent override()")
def implicit(self):
print("Parent implicit()")
def altered(self):
print("Parent altered()")
class Child(Parent):
def override(self):
print("Child override()")
def altered(self):
print("Child, before Parent altered()")
super(Child, self).altered()
print("Child, After Parent altered()")
dad = Parent()
son = Child()
dad.implicit()
son.implicit() # 隐式继承
dad.override()
son.override() # 显示覆盖
dad.altered()
son.altered() # 运行后替换
多类继承是指定义的类继承了多个类
class SuperFun(Child, BadStuff): # SuperFun 类同时继承 Child 和 BadStuff
pass
合成:直接使用别的类和模块
class Other:
def override(self):
print("Other override()")
def implicit(self):
print("Other implicit()")
def altered(self):
print("Other altered()")
class Child:
def __init__(self):
self.other = Other() # 调用 Other 类
def implicit(self):
self.other.implicit()
def override(self):
print("Child override()")
def altered(self):
print("Child, before Other altered()")
self.other.altered()
print("Child, after Other altered()")
son = Child()
son.implicit()
son.override()
son.altered()
继承可以让你在子类里隐含父类的功能,而合成则是利用模块和别的类中的函数调用达到相同的目的,