Learn Python The Hard Way学习(44) - 继承还是组成?
balabala...讲了一个故事,就不翻译了。
只要记着:我们要尽量简单的使用继承,或者用组合代替继承,而且做好不要使用多继承。
什么是继承?
继承被用来指明一个类可以从它的父类取得大部分或者全部的特征。当你写class Foo(Bar)的时候,继承就发生了。Foo类的实例和Bar类的实例一样工作。继承就是为了你能再Bar类中定义普通的方法,而在Foo类中定义特殊的方法。
当做了继承后,父类和子类有三个相互影响的方法:
子类的动作暗含了父类的动作
子类的动作覆盖了相应的父类动作
子类的动作改变了相应的父类动作
暗含继承
先在父类定义一个implicit函数,子类什么也不做。
[python]
class Parent(object):
def implicit(self):
print "parent implicit()"
class Child(Parent):
pass
dad = Parent()
son = Child()
dad.implicit()
son.implicit()
在子类中使用pass就是告诉python,这里是一个空的代码块。就是说子类完全继承父类的特征。运行代码的结果如下:
parent implicit()
parent implicit()
注意,我调用了son.implicit()在16行,但是子类并没有这个方法,它调用了父类的对应方法执行。这里告诉你,子类会自动取得父类的所有特征,不需要重复编写代码。
覆盖暗含
问题是有时候你希望子类继承的函数有不同的提现,解决办法就是覆盖父类的函数,定义一个同名的函数在子类中,代码如下:
[python]
class Parent(object):
def override(self):
print "parent override()"
class Child(Parent):
def override(self):
print "child override()"
dad = Parent()
son = Child()
dad.override()
son.override()
运行效果如下:
parent override()
child override()
正如你看到的,子类运行相应的函数的时候会运行覆盖过的函数,相当于子类的新版本。
改变之前或者之后
改变和覆盖有一些区别,我们需要先覆盖父类的函数,然后再通过super调用父类的函数,在调用的前后可以添加其他方法,例如如下:
[python] view plaincopy
class Parent(object):
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()
第9和11行比较重要,当我调用son.altered()的时候做了下面这些事情:
因为我已经覆盖了父类的函数altered,所以第9行会在子类调用altered的时候执行。
我希望在第9行后执行父类的altered,所以我使用了super。
在第10行我调用super(child, self).altered(),有点像不久前使用的getattr函数,不过这里是从继承的父类那里调用函数。
然后,父类的函数运行,并打印信息。
最后,从父类函数返回,继续运行剩下的子类的语句。
运行结果如下:
parent altered()
child, before parent altered()
parent altered()
child, after parent altered()
混合使用三个方法
[python] view plaincopy
class Parent(object):
def implicit(self):
print "parent implicit()"
def override(self):
print "parent override()"
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()
给代码加上注释,区别这三种方式,运行如下:
parent implicit()
parent implicit()
parent override()
child override()
parent altered()
child, before parent altered()
parent altered()
child, after parent altered()
使用super()的理由
现在有个麻烦,就是多重继承,意思是一个类继承了多个类,像下面这样:
class SuperFun(Child, BadStuff):
pass
就像是说:”创建一个SuperFun,同时继承Child和BadStuff类。
这样的话,当SuperFun实例有隐含的动作的时候,python需要去两个类中取寻找,这就必须有一定的顺序。Python使用一个叫“Method Resolution Order”(MRO)和C3算法实现。
由于MRO很复杂,Python不可能让你直接使用它,所以给了一个super方法让你调用,使用后python会自动实现内部的调用。
在__init__中使用super()
通常super()都是在__init__中使用的,完成父类的初始化,下面是一个例子:
class Child(Parent):
def __init__(self, stuff):
self.stuff = stuff
super(Child, self).__init__()
组成
继承很有用,但是另外一个方法可以使用类和模块最相同的事情,而不依赖隐含继承。下面这种方法可以简单的实现上面那三种方式。看例子:
[python]
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 other altered()"
self.other.altered()
print "child, after other altered()"
son = Child()
son.implicit()
son.override()
son.altered()
上面的代码我没有
补充:Web开发 , Python ,