Python类的继承和方法重写总结

发布时间:2019-09-07 08:11:19编辑:auto阅读(1675)

    Python类的继承和方法重写总结

     

     

    我们都知道类可以继承,通过继承可以实现代码的复用,使代码看起来更加简洁

     

    比如:

    Class B(A):
    Pass

     

    定义了一个名为B的类,它继承于A,我们把B叫做A的子类,A叫做B的超类(父类)。

     

    方法重写

    当子类定义了一个和超类相同名字的方法时,那么子类的这个方法将覆盖超类相同的方法(或称为重写)

     

    先借用两个例子:

    >>> class Bird:
    ...     def __init__(self):
    ...         self.hungry = True
    ...     def eat(self):
    ...         if self.hungry:
    ...             print 'Aaaah...'
    ...             self.hungry = False
    ...         else:
    ...             print 'No,thanks!'
    ...
    >>> b = Bird()
    >>> dir(b)
    >>> b.eat()
    Aaaah...
    >>> b.eat()
    No,thanks!
    >>>

    这个类定义了鸟的基本功能:吃

     

    再定义一个类,SongBirdBird的子类,SongBird会唱歌

    >>> class SongBird(Bird):
    ...     def __init__(self):
    ...         self.sound = 'Squawk!'
    ...     def sing(self):
    ...         print self.sound
    ...
    >>> sb = SongBird()
    >>> sb.sing()
    Squawk!
    >>> sb.eat()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 5, in eat
    AttributeError: SongBird instance has no attribute 'hungry'
    >>>

     

    SongBirdBird的一个子类,他继承了超类的eat方法,但调用时却报错了,提示没有hungry属性,为什么会这样呢?

     

    原因是SongBird的构造方法__init__()重写了,新的构造方法里没有任何关于hungry属性的代码。为了达到预期的效果,SongBird的构造方法必须调用父类的构造方法来确保进行基本的初始化。有两种方法能达到这个目的:调用超类的构造方法的未绑定版本,或者使用super函数。

     

     

    调用超类的构造方法的未绑定版本

    >>> class SongBird(Bird):
    ...     def __init__(self):
    ...         Bird.__init__(self)
    ...         self.sound = 'Squawk!'
    ...     def sing(self):
    ...         print self.sound
    ...

    SongBird类只添加了一行代码Bird.__init__(self)

    看下执行结果

     

    >>> sb = SongBird()
    >>> sb.eat()
    Aaaah...
    >>>

     

    在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(这称为绑定方法),但如果直接调用类的方法(比如Bird.__init__),就没有实例被绑定,这样的方法称为未绑定方法。

    通过将当前的实例作为self参数提供给未绑定方法,SongBird类就能使用其超类构造方法的所有实现。

     

     

    Super函数

    Super函数只能在新式类使用。当前类和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。

    那么就可以不用在SongBird的构造方法使用Bird,而直接使用super(SongBird,self)注意是逗号,不是.

    除此之外,__init__方法能以一种普通的(绑定)方式被调用

     

    >>> __metaclass__ = type
    >>> class Bird:
    ...     def __init__(self):
    ...         self.hungry = True
    ...     def eat(self):
    ...         if self.hungry:
    ...             print 'Aaaah...'
    ...             self.hungry = False
    ...         else:
    ...             print 'No,thanks!'
    ...

     

    >>> class SongBird(Bird):
    ...     def __init__(self):
    ...         super(SongBird,self).__init__()
    ...         self.sound = 'Squawk!'
    ...     def sing(self):
    ...         print self.sound
    ...
    >>> sb = SongBird()
    >>> sb.eat()
    Aaaah...
    >>> sb.eat()
    No,thanks!

     


关键字