day23:單繼承&多繼承&菱形繼承&__init__魔術方法

李博倫發表於2020-08-04

1.單繼承

  1.1 關於繼承的一些基本概念

  1.2 子類可以呼叫父類的公有成員

  1.3 子類無法呼叫父類的私有成員

  1.4 子類可以改寫父類的方法

2.多繼承

  2.1 多繼承的基本語法

  2.2 super用法

  2.3 self和super的區別

3.菱形繼承(鑽石繼承)

  3.1 super:用來解決複雜的多繼承呼叫順序

  3.2 mro列表:返回撥用順序列表

  3.3 issubclass和isinstance

  

單繼承

關於繼承的一些基本概念

1.什麼是子類?什麼是父類?如果一個類繼承另外一個類,該類叫做子類(衍生類),被繼承的類叫做父類(基類,超類)

2.繼承的種類:1.單繼承 2.多繼承 

3.object類:在python中,所有的類都預設繼承父類object

定義一個Human類,並定義一些屬性和方法:

class Human(object):
    hair = "黑色"
    sex = ""

    def cry(self):
        print("人類會哭")
    def eat(self):
        print("人類會吃東西")
    def __makebaby(self):
        print("人類會繁衍生息")

子父繼承之後,子類可以呼叫父類的公有成員

# 1.子父繼承之後,子類可以呼叫父類的公有成員
class Man(Human): # 定義Man類,繼承Human類
    pass

obj = Man()
print(obj.hair) # 子類Man直接呼叫父類的hair屬性
obj.cry() # 子類Man直接呼叫父類的cry方法

子父繼承之後,子類不能呼叫父類的私有成員

# 2.子父繼承之後,子類不能呼叫父類的私有成員
class Woman(Human):
    def pub_func(self):
        self.__makebaby()

obj = Woman()
obj.__makebaby() # error 子類無法直接呼叫父類的私有成員
obj.pub_func() # error 即使在子類定義pub_func用來存放私有成員,那也是父類的私有成員,而非子類的

子父繼承之後,子類可以改寫父類中的方法

子父繼承之後

1.如果子類裡面有該成員屬性或者方法,優先呼叫自己的

2.如果子類沒有該成員,則呼叫父類中的成員

3.如果子類父類都沒有該成員,則直接報錯

class Children():
    sex = ""
    def cry(self):
        print("小孩會哇哇哇哭")
obj = Children()
obj.cry() # 子類有cry方法,優先使用子類的

多繼承

多繼承的基本語法

# 1.基本語法
class Father():
    property = "爸爸英姿颯爽"
    def f_hobby(self):
        print("爸爸喜歡抽菸")

class Mother():
    property = "媽媽傾國傾城"
    def m_hobby(self):
        print("媽媽喜歡打麻將")

class Daughter(Father,Mother): # Daughter類繼承Father類和Mother類
    pass

# 例項化物件
obj = Daughter()
print(obj.property) # 優先會繼承Father類的property
obj.m_hobby() # 媽媽喜歡打麻將

super用法

1.super本身是一個類,super()是一個物件,用來呼叫父類的繫結方法

2.super()只應用在繫結方法中,預設自動傳遞self物件(前提super所在作用域存在self)

3.super用途:解決複雜的多繼承呼叫順序

class Father():
    property = "爸爸英姿颯爽"
    def f_hobby(self):
        print("爸爸喜歡抽菸")

class Mother():
    property = "媽媽傾國傾城"
    def m_hobby(self):
        print("媽媽喜歡打麻將")

class Son(Father,Mother):
    property = "兒子喜歡玩遊戲"

    # 1.利用類來呼叫父類的成員
    def skill1(self):
        Father.f_hobby()
        print(Mother.property)
    # 2.利用物件呼叫父類的成員
    def skill2(self):
        self.m_hobby()
        print(self.property)
    # 3.利用super呼叫父類的屬性和方法
    """
    super()只呼叫父類的相關公有成員,不會呼叫自己的本類成員,父類沒有直接報錯
    super()在呼叫父類方法時,只呼叫父類的繫結方法,預設傳遞引數是本類的物件self
    """
    def skill3(self):
        print(super().property)
        super().m_hobby()

obj = Son()
obj.skill1()
obj.skill2()
obj.skill3()

self和super的區別

self和super()的區別:

self在呼叫成員時,先看看自己的類物件是否存在該成員

  1.如果有呼叫自己的.

  2.如果子類自己沒有,呼叫父類的

  3.如果子類和父類都沒有,則直接報錯

super()在呼叫成員時,只呼叫父類的相關成員(屬性,繫結方法)

  永遠不會呼叫自己的,如果父類沒有,直接報錯

菱形繼承(鑽石繼承)

super:用來解決複雜的多繼承呼叫順序

class OldWoman():
    pass

class Human():
    pty = 4
    def feelT(self):
        print("原始人類熱了,吃冰塊1")
        print(self.pty)
        print("原始人類冷了,生火取暖2")

class Man(Human):
    pty = 3
    def feelT(self):
        print("現代男人熱了,光膀子3")
        super().feelT()
        print("現代男人冷了,穿大棉襖4")

class Woman(Human):
    pty = 2
    def feelT(self):
        print("現代女人熱了,吹空調5")
        super().feelT()
        print("現代女人冷了,喝熱水6")

class Children(Man,Woman):
    pty = 1
    def feelT(self):
        print("現代小孩熱了,哇哇哭7")
        super().feelT()
        print("現代小孩冷了,也要哭8")

obj = Children()
obj.feelT()

執行順序是73512648,繼承順序Children->Father->Mother->Human

執行完畢之後還需要將每個類中的feelT方法中剩餘的程式碼執行完

整個程式碼的執行順序像遞迴中"一來一回"的過程

mro列表:返回撥用順序列表

mro列表:super用途的一個體現,解決複雜的多繼承呼叫順序關係

類.mro() 返回的是方法呼叫順序列表,針對於多繼承下的同名方法,按照順序依次的進行呼叫

lst = Children.mro()
print(lst)
"""
[
<class '__main__.Children'>, 
<class '__main__.Man'>, 
<class '__main__.Woman'>, 
<class '__main__.Human'>, 
<class 'object'>
]
"""

issubclass 判斷子父關係 (應用在類當中,判斷子父關係)

# issubclass 判斷子父關係 (應用在類當中,判斷子父關係)
"""只要在一條繼承鏈上即可(有血緣關係)"""
res = issubclass(Children,Man)
print(res)
res = issubclass(Children,Woman)
print(res)
res = issubclass(Children,Human)
print(res)
res = issubclass(Children,(Human,Woman,Man,OldWoman))
print(res)
res = issubclass(Children,OldWoman)
print(res)

isinstance (應用在物件和類之間,判斷型別)

# isinstance(應用在物件和類之間,判斷型別)
"""只要在一條繼承鏈上即可(有血緣關係)"""
res = isinstance(obj,Children) # True
res = isinstance(obj,Human) # True
res = isinstance(obj,(Human,Children,Woman)) # True
res = isinstance(obj,OldWoman) # False

問題:列印的值是多少?

如圖所示:

魔術方法之__init__方法

__init__方法簡介

1.觸發時機:例項化物件,初始化的時候觸發

2.功能:為物件新增成員

3.引數:引數不固定,至少一個self引數

4.返回值:無

 

相關文章