情形一:三重继承关系:son继承自Father, Father继承自GrandFather
测试目的:son类内调用父类函数的方法,有三种方法
if 1:
print('+'*30)
#类的继承
class GrandFather():
def __init__(self):
print('GrandFather init!')
def gf_test(self):
print('grandfather here!')
class Father(GrandFather):
def __init__(self):
super().__init__()
print('Fahter init!')
def fa(self):
print('father here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
class Son(Father):
def __init__(self):
super().__init__()
print('Son init!')
def so(self):
print('son here!')
#在类内调用父类的函数(方式一)
#super().fa()
#super().gf_test()
#在类内调用父类的函数(方式二)
#self.fa()
#self.gf_test()
#在类内调用父类的函数(方式三)
Father.fa(self)
GrandFather.gf_test(self)
s = Son()
s.so()
print('+'*30)
情形二:Son继承自两个父类Father和Father1,而这两个父类都继承自同一个父类GrandFather, Father和Father1的类函数一样。
测试目的:Son在类内调用父类与继承顺序。
1. Father和Father1中对gf_test函数进行重写了,所以在Father和Father1类内部,通过self.gt_test是调用的自己(Father和Father1)的gf_test,而不是GrandFather.gf_test。
2. Son类内调用gf_test函数时,由于自身没有实现gf_test函数,所以不管通过self还是super()调用gf_test时,都是调用是父类的gt_test,但问题来了,那就是Father和Father1甚至GrandFather中都有gt_test函数,具有调用是哪个类的gf_test函数呢?答案是Father中的gt_test函数。这要分三种情况进行讨论:
(1)在Son类内用self.gf_test调用gf_test函数时
根据同名函数调用顺序:先自己的类->父类->父类的父类->父类的父类的父类...;
如果直接继承的父类有多个,如本例中,Son有两个父类Father和Father1,那么调用顺序是:自己的类->父类1->父类2->父类3....
(2)在Son类内用super().gf_test调用gf_test函数时
调用顺序就是:父类->父类的父类->父类的父类的父类->......
在直接继承的父类有多个时,调用顺序是:父类1->父类2->父类3.....
(3)直接用父类名称调用gf_test时,如Father1.gf_test(),那么就是直接就调用的是该父类中的函数
if 1:
print('+'*30)
#类的继承
class GrandFather():
def __init__(self):
print('GrandFather init!')
def gf_test(self):
print('grandfather here!')
class Father(GrandFather):
def __init__(self):
super().__init__()
print('Fahter init!')
def fa(self):
print('father here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
def gf_test(self):
print('Father here!')
class Father1(GrandFather):
def __init__(self):
super().__init__()
print('Fahter1 init!')
def fa(self):
print('father1 here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
def gf_test(self):
print('Father1 here!')
class Son(Father,Father1):
def __init__(self):
super().__init__()
print('Son init!')
def so(self):
print('son here!')
#在类内调用父类的函数(方式一)
#super().fa()
super().gf_test()
#在类内调用父类的函数(方式二)
#self.fa()
#self.gf_test()
#在类内调用父类的函数(方式三)
#Father.fa(self)
#GrandFather.gf_test(self)
s = Son()
s.so()
print('+'*30)
#输出
++++++++++++++++++++++++++++++
GrandFather init!
Fahter1 init!
Fahter init!
Son init!
son here!
Father here!
++++++++++++++++++++++++++++++
理解本质,本质:函数的查找顺序是按类构造时的逆顺序进行的。请看下面的例子
继承关系说明:
(1)Father和Father1都继承自GrandFather, Son 继承自 Father和Father1
(2)构造函数的调用顺序:GrandFather->Father1->Father->Son
在Father中的super()是Fahter1,而不是GrandFather。相当于Father1成了Father的父类。
print('+'*30)
#类的继承
class GrandFather():
def __init__(self):
print('GrandFather init!')
def gf_test(self):
print('grandfather here!')
def special_test(self):
print('I am special!')
class Father(GrandFather):
def __init__(self):
super().__init__()
print('Fahter init!')
def fa(self):
print('!Father here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
def gf_test(self):
print('@Father here!')
class Father1(GrandFather):
def __init__(self):
super().__init__()
print('Fahter1 init!')
def fa(self):
print('Father1 here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
def gf_test(self):
print('#Father1 here!')
class Son(Father,Father1):
def __init__(self):
super().__init__()
print('Son init!')
def so(self):
print('son here!')
#在类内调用父类的函数(方式一)
#super().fa()
#super().gf_test()
#在类内调用父类的函数(方式二)
#self.fa()
self.special_test()
#self.gf_test()
#在类内调用父类的函数(方式三)
#Father.fa(self)
#GrandFather.gf_test(self)
s = Son()
s.so()
print('+'*30)
#输出
++++++++++++++++++++++++++++++
GrandFather init!
Fahter1 init!
Fahter init!
Son init!
son here!
I am special!
++++++++++++++++++++++++++++++
如下的继承关系看着很复杂,其实是最简单的情况一种最简单的叠加。
(1)GrandFather和GrandFather1没有任何关系
(2)Father继承自GrandFather,而Father1继承自GrandFather1,所以Father与Father1也没有任何关系
(3)super()如果没有参数,则表示直接父类,所以Son的super()是Father, Father的super()是GrandFather.
而Father1的super是GrandFather().所以Son在构造时,只有 " Father init " ,而没有 " Father1 init ",所以本例中的构造函数是不规范的,因为没有对Father1进行构造。因此在Son中是没有办法调用Father1的类变量d的
(4)当然super()是可以带参数,有两个参数。比如在Son类中,super(Father1,self)是Father1的父类,即GrandFather
if 1:
print('+'*30)
#类的继承
class GrandFather():
def __init__(self):
print('GrandFather init!')
def gf_test(self):
print('grandfather here!')
def special_test(self):
print('I am special!')
class Father(GrandFather):
def __init__(self):
super().__init__()
print('Fahter init!')
def fa(self):
print('!Father here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
def gf_test(self):
print('@Father here!')
class GrandFather1():
def __init__(self):
print('GrandFather1 init!')
def gf_test(self):
print('grandfather1 here!')
def special_test1(self):
print('I am special11!')
class Father1(GrandFather1):
def __init__(self,d):
super().__init__()
self.d = d
print('Fahter1 init!')
def fa(self):
print('Father1 here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
def gf_test(self):
print('#Father1 here!')
class Son(Father,Father1):
def __init__(self):
super().__init__() #Son的直接父类是Father,而与Father1无关,所以此处只是对Father进行了构造
print('Son init!')
def so(self):
print('son here!')
#在类内调用父类的函数(方式一)
#super().fa()
#super().gf_test()
#在类内调用父类的函数(方式二)
#self.fa()
self.special_test1()
#print(self.d) #会报错
#self.gf_test()
#在类内调用父类的函数(方式三)
#Father.fa(self)
#GrandFather.gf_test(self)
s = Son()
s.so()
print('+'*30)
#输出
++++++++++++++++++++++++++++++
GrandFather init!
Fahter init!
Son init!
son here!
I am special11!
++++++++++++++++++++++++++++++
本例是上例的规范版本
if 1:
print('+'*30)
#类的继承
class GrandFather():
def __init__(self):
print('GrandFather init!')
def gf_test(self):
print('grandfather here!')
def special_test(self):
print('I am special!')
class Father(GrandFather):
def __init__(self):
super().__init__()
print('Fahter init!')
def fa(self):
print('!Father here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
def gf_test(self):
print('@Father here!')
class GrandFather1():
def __init__(self):
print('GrandFather1 init!')
def gf_test(self):
print('grandfather1 here!')
def special_test1(self):
print('I am special11!')
class Father1(GrandFather1):
def __init__(self,d):
self.d = d
super().__init__()
print('Fahter1 init!')
def fa(self):
print('Father1 here!')
super().gf_test()
self.gf_test()
GrandFather.gf_test(self)
def gf_test(self):
print('#Father1 here!')
class Son(Father,Father1):
def __init__(self):
super().__init__()
Father1.__init__(self,10) #显式对Father1进行构造
print('Son init!')
def so(self):
print('son here!')
#在类内调用父类的函数(方式一)
#super().fa()
#super().gf_test()
#在类内调用父类的函数(方式二)
#self.fa()
self.special_test1()
print(self.d)
#self.gf_test()
#在类内调用父类的函数(方式三)
#Father.fa(self)
#GrandFather.gf_test(self)
s = Son()
s.so()
print('+'*30)
#输出
++++++++++++++++++++++++++++++
GrandFather init!
Fahter init!
GrandFather1 init!
Fahter1 init!
Son init!
son here!
I am special11!
10
++++++++++++++++++++++++++++++