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

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.返回值:無