原文链接:http://learnpythonthehardway.org/book/ex44.html
在关于英雄打败邪恶的坏蛋的童话故事里面总有一个非常黑暗的地带。它可能是一个洞穴,一片森林,甚至另一个星球,反正就是每个人都知道主角一定会去的一个地方。当然,在你简短的了解了恶棍是怎么坏之后,是的,主角英雄就必须去往那该死的森林杀了那个坏蛋了。之后就英雄在那个邪恶的森林里陷入了各种有生命危险的情况。
你很少看到在童话故事中主角会聪明的避免发生上述整个情况。你从没听主角这样说过,“等一分钟,如果我把自己的命运交给大海随波逐流我可能会死去,那么她就不得不去和一个叫做Humperdink的丑陋的王子结婚。Humperdink啊!我想我宁愿待着这里做一个农家男孩靠收租金过活。“ 如果他那样做了的话,那么就不会陷入火海,不会有死亡,不会有动乱,不会有刀光剑影,不会有巨人,或者其它任何故事中有的东西。因为这些,这些故事中的黑暗地带就像是一个黑洞一样无论这些主角怎么做都会被拉进来。
在面向对象编程中,继承就是一片危险的地带。有经验的程序知道怎么避免这些危险,因为他们对黑暗地带继承于邪恶之母的多重继承有更深的了解。她喜欢用它错中复杂的巨大牙齿吞噬软件和项目,然后慢慢咀嚼。但是这片地带拥有强大的功能,所以几乎每个程序员都必须去学会通过它,并且在真正能称作程序员之前从邪恶女皇面前存活下来。你如果不能抵抗继承这片黑暗地带的拖拉的话,那么你就走进去吧。在经过冒险之后你就会学会远离这片该死的黑暗地带了,如果你再一次不得不去的话就带上一支军队前往吧。
上面只是一个简单有趣的方式来告诉你避免一个叫做继承的一些东西。那些现在正在和邪恶女皇战斗的的程序员可能会告诉你应该勇敢的走进去。他们之所以这么说是他们需要你的帮助因为他们可能创建了太多无法处理的东西。但是你永远要记住下面这句话:大多数的使用的基础可以被简化或者用组合去替代,而至于多重继承应该不惜一切代价避免。
继承是什么?
隐式继承
class Parent(object):
def implicit(slef):
print "PARENT imlicit()"
class Child(Parent):
pass
dad = Parent()
son = Child()
dad.implicit()
son.implicit()
在 class Child中使用的pass:是你告诉Python你想要一个空模块。就是创建了一个命名为 Child 的类但是在里面没有定义任何新的东西。因此它所有的行为操作都继承于Parent类。当你运行该脚本的时候可以得到下面的结果:
c:\>python ex44-1.py
PARENT imlicit()
PARENT imlicit()
可以注意到即使我在13行调用 son.implicit() ,即使Child类没有定义一个 implicit的函数,它还是调用了在Parent中定义的 implicit函数。这就是向你展示了,如果你在一个基类(例如:Parent类)中定义了一个函数,那么在所有的子类(例如:Child类)中就会自动得到这些属性。这对于在很多类中要写重复的代码是非常有用的。
显示重写
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()
在这个示例中我在两个类中都命名了一个名为 override 的函数,那么让我们来运行下看看发生了什么。
c:\>python ex44-2.py
PARENT override()
CHILD override()
你可以看见,当运行到14行的时候,它执行的是 Parent.override 函数因为 dad 是Parent类的一个实例对象。但是当运行到第15行的时候它打印出来的却是 Child.override 的消息,因为 son 是Child的一个实例化对象并且Child通过定义自己版本的函数来重载了override函数。
修改前或者修改后
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行,在Child类中当调用 son.altered() 函数时做了如下操作:
PARENT altered()
CHILD ,BEFORE PARENT altered()
PARENT altered()
CHILD ,AFTER PARENT altered()
三种组合
class Parent(object):
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 ,slef).altered()
print "CHILD ,AFTER PARENT altered()"
dad = Parent()
son = Child()
dad.implicit()
son.implicit()
dad.override()
son.override()
dad.altered()
son.altered()
通读代码中的每一行,并且写一个注释来解释该行做了什么操作,是否重载。然后运行该脚本看看是不是你所期望的结果:
c:\>python ex44-4.py
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类。
带 __init__ 使用 super()
class Child(Parent):
def __init__(self ,stuff):
self.stuff = stuff
super(Child ,self).__init__()
这个非常想上面提到的 Child.altered 的例子,我在 __init__ 函数中设置的一些变量在Parent的__init__函数初始化之前。