1. 程式人生 > >Python學習之路-----類繼承

Python學習之路-----類繼承

繼承

        如果兩個類具有同名的屬性和方法的時候就可以使用繼承,例如B類繼承A類,那麼在B類中就有類A中的屬性以及方法。被繼承的類叫做父類,繼承的而得類叫做子類。繼承是面向物件程式設計的第二個特性。一般來說,父類是一些公有的屬性和方法,因此類的繼承能夠減少程式碼的冗餘,提升程式碼的可讀性,提高開發效率。幾乎在所有面向物件的程式設計中,object類是所有物件的最終繼承的類,“祖宗!”。

    格式:   class 子類名(父類名):

類方法的呼叫順序:

        子類----->父類----->二級父類------>.......----->object

         繼承關係是沒有限制的,當在子類物件呼叫一個方法的時候,如果子類的定義中有這個方法的定義就呼叫子類中的那個方法;如果沒有那個方法的定義,就往上看父類有沒有這個方法,如果一直到object類都沒有找到這個方法的定義就會報錯。

重寫父類的方法

        當子類中定義了和父類的一個同名方法時叫做重寫父類的方法。一般來說當父類的方法不能滿足子類需求的時候就需要在子類中重寫這個方法。

class Dog:

    def eat(self):
        print("吃狗糧")

    def description(self):
        print("this is a dog!")

class JunQuan(Dog):

    def eat(self):
        print("吃肉")

jq = JunQuan()
jq.eat()
jq.description()


結果:
吃肉
this is a dog!

子類中呼叫父類的方法

         子類物件如果呼叫和父類中同名的方法時預設只會呼叫自己的方法,在方法中使用super(子類名,self)便可呼叫到父類的方法。如下程式碼:

class Dog:
    def eat(self):
        print("吃狗糧")


class JunQuan(Dog):
    def eat(self):
        super(JunQuan, self).eat()  #得到JuanQuand的父類,然後呼叫它的eat()方法。
        print("吃肉")

jq = JunQuan()
jq.eat()

結果:
吃狗糧
吃肉

重寫__init__方法

        定義子類物件的時候會呼叫父類的__init__方法來初始化自身的屬性,如果子類中含有父類中沒有的屬性就需要重寫父類的__init__方法。如下程式碼。此時會發現如果在子類的__init__方法中只定義了子類特有的屬性,那麼繼承自父類的屬性反而沒有了。因此如果開啟最後一行的註釋會報錯。

class Dog:
    def __init__(self):
        self.name = "旺旺"

class JunQuan(Dog):
    def __init__(self):
        self.attri = "搜救"

jq = JunQuan()
print(jq.attri)
#print(jq.name)

結果:
搜救

正確的方式是在子類的__init__方法中使用super(子類名,self).__init__(父類屬性的引數),此時子類的__init__方法需要在定義的時候新增一個引數。一般來說super()是寫在子類__init__方法的第一行的。

class Dog:
    def __init__(self,name):
        self.name = name

class JunQuan(Dog):
    def __init__(self,name):
        super(JunQuan, self).__init__(name)
        self.attri = "搜救"

jq = JunQuan("軍犬")
print(jq.attri)
print(jq.name)

結果:
搜救
軍犬

私有屬性和方法的繼承問題

        類繼承只是針對類的公有屬性和方法,不能繼承類的私有屬性和方法。子類如果想要訪問父類的私有屬性只能通過父類自身的set()和get()方法。

多繼承

        當子類想同時擁有多個父類的方法時可以 同時繼承多個父類,格式: class 子類名(父類1,父類2)

class A:
    def funA(self):
        print("function from A")

class B:
    def funB(self):
        print("function from B")

class C(A,B):
    pass

c = C()
c.funA()
c.funB()

結果:
function from A
function from B

        在多繼承中如果兩個父類中有同名的方法,那麼在子類呼叫方法的時候預設呼叫的是第一個父類的方法。

class A:
    def funA(self):
        print("function from A")
    def discription(self):
        print("this is A")

class B:
    def funB(self):
        print("function from B")
    def discription(self):
        print("this is B")

class C(A,B):
    pass

c = C()
c.funA()
c.funB()
c.discription()

結果:
function from A
function from B
this is A
檢視繼承鏈:子類名.__mro__()