继承的覆盖以及调用基类的问题

作者: LiHui 分类: Python 发布时间: 2015-05-10 16:39

派生出类有一些方法覆盖问题,以及调用基类的方法

__author__ = 'LiHui'

class MyBook(object):
    def __init__(self):
        print 'MyBook __init__'

class MyCookBook(MyBook):
    def __init__(self):
        print 'MyCookBook __init__'

if __name__ == '__main__':
    MyCookBook()

这里MyCookBook由类MyBook派生,但是他们却有着相同命名的构造器__init__方法,那么尽管子类里继承了基类的__init__,但由于子类里定义了相同的__init__方法,那么基类里的__init__就会被覆盖,输出结果

MyCookBook __init__

假如做一些改编,将子类的__init__重命名

__author__ = 'LiHui'

class MyBook(object):
    def __init__(self):
        print 'MyBook __init__'

class MyCookBook(MyBook):
    def foo(self):
        print 'MyCookBook __init__'

if __name__ == '__main__':
    MyCookBook()

这里将__init__修改为foo,输出结果为

MyBook __init__

可见这时候不存在构造器方法覆盖问题,而且foo没有通过类实例来调用,所以不会打印其函数信息,但是最终打印了基类构造器的输出信息,这里说明了,如果从带有构造器__init__的基类里派生出一个子类,假如不去覆盖掉__init__,它将会被继承,并自动调用

假如想在子类里调用基类方法,可以通过super()方法来实现,不仅能找到对应的基类,而且还能传进去self,这样,就可以在子类里通过super()来调用基类方法,最终只需要操作子类

__author__ = 'LiHui'

class MyBook(object):
    def __init__(self):
        print 'MyBook __init__'

class MyCookBook(MyBook):
    def __init__(self):
        super(MyCookBook, self).__init__()
        print 'MyCookBook __init__'

if __name__ == '__main__':
    MyCookBook()

这样就能输出结果

MyBook __init__
MyCookBook __init__

但是,下面这种指出基类并调用方法的方式,也能得出结果

__author__ = 'LiHui'

class MyBook(object):
    def __init__(self):
        print 'MyBook __init__'

class MyCookBook(MyBook):
    def __init__(self):
        MyBook.__init__(self)
        print 'MyCookBook __init__'

if __name__ == '__main__':
    MyCookBook()

这里看上去更醒目,但是维护起来不如super那么直接,假如后来有修改基类名字,super根本不需要关心你的修改,而这种方式必须重新查看修改后的类名,而且假如有很多出都有这种调用方式,改动还是较多的

但是有一点要注意的就是,如果是这种传递方法,调用基类方法的时候一定要传递一个self参数,否则会出现下面报错

TypeError: unbound method foo() must be called with MyBook instance as first argument (got nothing instead)

纯属恶搞

浙ICP备16024533号

浙公网安备 33010802007459号