了解類的繼承和super函數(shù)

今天來了解下類的繼承和super函數(shù),為之后我們閱讀他人代碼做鋪墊。

我們首先來看一個(gè)列子:

class A:
    def case1(self):
        print("case1_A")

    def case2(self):
        print("case2_A")

    def case3(self):
        print("case3_A")

#B類繼承父類A類,B類便擁有了A類的所有函數(shù)
class B(A):
    def case1(self):
        print("case1_B")

    def case2(self):
        print("case2_B")
        return "case2_B"

#C類繼承父類B類,C類便擁有了A類的所有函數(shù)
class C(B):

    def case2(self):
        print(super(C,self).case2(),"+ case2_C")


#實(shí)例化并執(zhí)行
A_Test = A()
A_Test.case1()
A_Test.case2()
A_Test.case3()
print("*"*10)

B_Test = B()
B_Test.case1()
B_Test.case2()
B_Test.case3()
print("*"*10)

C_Test = C()
C_Test.case1()
C_Test.case2()
C_Test.case3()
print("*"*10)

以下是打印結(jié)果:

case1_A
case2_A
case3_A
**********
case1_B
case2_B
case3_A
**********
case1_B
case2_B  #父類中的函數(shù)被實(shí)例化,并執(zhí)行
case2_B + case2_C  #得到了父類中函數(shù)的返回值后,做了二次修改。
case3_A

從例子中我們得出以下結(jié)論:

  1. python中用class B(A)的形式可以繼承父類的方法。
  2. 繼承父類后,子類會擁有父類的所有方法,即使沒有聲明,比如C_Test.case3()。
  3. 繼承的父類可以被覆蓋(重寫),只需要在子類中使用父類同名的函數(shù)名,比如B_Test.case1()
  4. 我們可以通過super函數(shù),實(shí)例化父類并在父類函數(shù)返回值的基礎(chǔ)上做二次開發(fā),比如C_Test.case2()
    這里需要注意,super(C,self).case2()super函數(shù)中的參數(shù)C,雖然是當(dāng)前子類的類名,但實(shí)際是將子類 C 的對象轉(zhuǎn)換為父類 B 的對象,所以每次看到函數(shù)中出現(xiàn)super函數(shù),實(shí)際是調(diào)用父類的函數(shù)或?qū)傩远皇潜绢惖摹?/li>

以下是super函數(shù)的語法:
super(type[, object-or-type])
參數(shù):
type -- 類。
object-or-type -- 類,一般是 self

接下來,我們修改原例子,來說明下屬性的繼承:


class A:
    def __init__(self):
        self.val1 = "A"
        self.val2 = "A"
        self.val3 = "A"

#B類繼承A類
class B(A):
    def __init__(self):
        # super(B,self) 首先找到 B 的父類(就是類 A),然后把類 B 的對象轉(zhuǎn)換為類 A 的對象
        super(B, self).__init__()
        self.val1 = self.val1 + "B"

#C類繼承B類
class C(B):
    def __init__(self):
        super(C, self).__init__()


#實(shí)例化并執(zhí)行
A_Test = A()
print(A_Test.val1)
print(A_Test.val2)
print(A_Test.val3)
print("*"*10)

B_Test = B()
print(B_Test.val1)
print(B_Test.val2)
print(B_Test.val3)
print("*"*10)

C_Test = C()
print(C_Test.val1)
print(C_Test.val2)
print(C_Test.val3)

以下是打印結(jié)果:

A
A
A
**********
AB
A
A
**********
AB
A
A

從例子中我們得出以下結(jié)論:

  1. super(自身類名, self).init()的形式,可以讓子類繼承父類的屬性。如:C_Test.val3
    這里需要注意,子類可以通過class B(A)的形式來繼承父類的函數(shù),但無法繼承父類的屬性(人家本來就是self.xxxx的存在著,只有自身類可用),所有需要繼承父類屬性時(shí)必須使用super函數(shù)或?qū)嵗割?,否則程序會報(bào)錯(cuò)。
  2. super函數(shù)也同樣可以繼承并重寫父類的屬性或做二次修改。如:B_Test.val1

總結(jié):
我們假設(shè)要一起開一個(gè)面包工坊,我們首先造了一個(gè)經(jīng)典白切吐司的流水線(基礎(chǔ)父類),其中包含了塑型,烘培,切片等方法(函數(shù)),也包含了面包原料,添加劑等屬性(變量)。
之后我們又準(zhǔn)備推出我們都喜歡的全麥切片面包(子類),那么父類中大部分的方法和屬性都是可以被繼承的,因?yàn)樗麄儽举|(zhì)上都是面包,只是子類需要對父類的方法或?qū)傩赃M(jìn)行重寫或二次開發(fā)。
以上的比喻也是面向?qū)ο缶幊痰脑?,一切皆對象,而無論是類的繼承也好,super函數(shù)也好,目的都是為了繼承與復(fù)用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容