当前位置:编程学习 > python >>

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 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,