python类继承

 情形一:三重继承关系: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
++++++++++++++++++++++++++++++

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值