python:多继承中的’‘那些事’’

相信大家在学习 《python面向对象——多继承》的时候,都知道:python支持多继承,以及多层继承。但是在第一次学习的时候,肯定会遇到一些父类同名方法,以及子类和多个父类同名方法的问题,有时候我们不知道他是如何继承并执行的,下面这篇文章触动了你我的心声!

继承

1、多继承

所谓多继承就是说,子类一下子直接继承了多个父类,这种情况就叫做多继承。

(1)格式:
class Person(object):
    pass
class Father(object):
    pass
class Mather(object):
    pass
# 多继承在这
class My(Person,Father,Mather):
    pass

相信大家在学习多继承的时候,肯定会遇到父类方法同名的问题,此时子类会去执行哪一个呢?那如果子类也有同名方法,那么又会去执行哪一个呢?

(2)多继承细则

大家都知道init方法是在对象实例时要执行的魔方方法,并且使用他可以给对象创建属性,也就是所说的在类中创建属性,那么当在继承中又会有怎样的效果呢?

(2)子类继承了多个父类,子类会继承父类的不同名方法

(1)当子类继承了多个父类,但是此时该子类没有init方法,而其他父类都拥有,那么在通过子类成功创建对象后,执行的init方法为:继承的第一个父类,所以可以在外部调用该父类的属性。

(2)当子类继承了多个父类,但是此时子类也拥有init方法,那么这个时候就造成了一种现象——重写,所以在外部通过子类成功创建对象后,会默认执行子类重写的魔方方法方法init,其他方法在特定条件下均可造成重写

2、多层继承

所谓多层继承:就是子类继承了一个父类,但是这个父类又继承了一个父类,对于子类来说它继承了两次,一次是直接继承,一次是间接继承,这种情况我们称之为多层继承。

(1)格式:
class Person(object):
    pass
# Father类直接继承了Person
class Father(Person):
    pass
# my类直接继承了Father类,间接继承了Person类
class My(Father):
    pass
(2)多层继承细则

其实多层继承和多继承的原理是一样的,但是他们还有写不同之处,就在于init魔方方法上。

(1)当子类直接继承了一个父类,又间接继承了一个父类,而子类中无init方法,而两个父类中都要,那么当通过子类成功创建对象后,会默认执行直接继承的父类的init方法,所以就可以访问直接继承的父类的属性

(2)当子类,间接继承的父类,直接继承的父类都有同名方法,那么就造成了重写,就会默认执行子类重写的方法,其实这里和上一个一样的,就不做太多的文章了

3、继承链

所谓继承链,就是说该类直接或间接继承了多少个父类,并且继承的顺序是什么,也就是先继承哪个父类,后继承那个父类,这个是可以明显看出来的,那么该如何查看呢?

格式:

print(子类.__mro__)
# 示例
# 我这里是多层继承
print(WuKong.__mro__)

运行结果:

(<class '__main__.WuKong'>, <class '__main__.PT'>, <class '__main__.Tang'>, <class 'object'>)

# 注意:第一个类该子类
# 因为我这里是多层继承,所以直接继承的父类是第二个,如果说是多继承,那么第二个就是第一个继承的父类
# 第三个为间接继承的父类
# 最后一个为object类,因为任何自定义类都来继承子object类

4、子类造成重写后,如何调用父类的方法

(1)直接调用法

所谓直接调用法,就是跟对象调用方法类似,只不过这里不是使用对象那个调用,而是使用父类名调用

格式:

# 父类名.方法名(self)
# 示例
Tang.__init__(self)
# 此时就可以使在外部用通过子类创建的对象调用该父类的属性

注意:这个 self 作为一个参数是将该子类的实例对象传入父类的方法,通过父类的self接收子类的self来进行调用的,所以self一定一定,切记不能丢

(2)super( )函数

super( )函数我想学过Java的人肯定不陌生,这个与c# 中的 base 关键字功能方面差不多类似,不过在python中 super( )函数可是有大讲究的。

格式:

super(子类名,self).父类同名方法
# 注意:这里调用的是继承链后一个类中的同名方法,也就是子类后的第一个类
super(WuKong,self).__init__()
# 那么,如何调用继承链后第二个类的同名方法,也就是继承的第二个父类呢?
super(子类后一个类,self).父类同名方法
# 其实这里的意思就是说:要调用子类的父类的父类的方法,就不是使用该子类了,因为中间差了一辈,所以这里只能用父类调用父类的父类来实现
# 其实含义一种讲究
super().父类同名方法
# 注意:这里省略了参数,那么意义就不同了,这样做的是调用当前子类的直接父类的同名方法,也就是继承链第二个类,第一个类是子类自身嘛

以上文章均为自己在一天的学习中不断总结出来的难懂知识点,但愿对大家能有一点的帮助作用,当然,如果本篇文章有什么不完善的地方,或者不够准确的地方,还请各位码友能够指点,期待大家的共同进步,加油!