1. 程式人生 > 其它 >繼承與多型

繼承與多型

一、繼承

    繼承是一種建立新類的方式,在python中,新建的類可以繼承一個或者多個父類,新建的類可以稱為子類或者父類,被繼承的類可以稱為父類或者基類。

    子類可以使用父類中的屬性或者方法

    解決了類與類之間程式碼冗餘的問題

    在python2當中,繼承了objcet類的子子孫孫類都稱為新式類,沒有繼承的都稱為經典類

    在python3中,沒有區分經典類和新式類,都是新式類

    單繼承

      只繼承一個父類的被稱為單繼承

      單繼承下的屬性查詢

class Foo():
    def f2(self):
        print('from Foo')
    def f1(self):
        print('from Foo')

class Bar(Foo):
    def f1(self):
        print('from f1')

# 當該屬性或方法在子類中,則使用子類的,如果沒有則去父類中尋找,父類中也沒有就會報錯
obj = Bar()
obj.f1()  # from f1 
obj.f2()  # from Foo
obj.f3()  # 報錯

  


# 練習1

class Foo: def f1(self): print('Foo.f1') def f2(self): # print('Foo.f2') self.f1() class Bar(Foo): def f1(self): print('Bar.f1') obj = Bar() # {} obj.f2()
# 練習2 class Foo: def __f1(self): # _Foo__f1() print('Foo.f1') def f2(self): # print('Foo.f2') self.__f1() # _Foo__f1() class Bar(Foo): def __f1(self): # # _Bar__f1() print('Bar.f1') obj = Bar() # {} obj.f2()

   

    多繼承

      繼承多個父類的被稱為多繼承

     多繼承下的屬性查詢

       多繼承下的屬性查詢一般分為按照廣度查詢和按照深度查詢

        新式類都是按照廣度查詢的

class G:
    def test(self):
        print('from A')


class E(G):
    def test(self):
        print('from B')
    pass

class F(G):
    def test(self):
        print('from C')
    pass


class B(E):
    def test(self):
        print('from D')
    pass

class C(F):
    def test(self):
        print('from B')
    pass
class D(G):
    def test(self):
        print('from B')
    pass

class A(B,C,D): def test(self): print('from A') pass print(F.mro()) # 查詢順序 [<class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>] f1 = F() f1.test()

  

      

      經典類都是按照深度查詢順序查詢的

class G:
    def test(self):
        print('from A')


class E(G):
    def test(self):
        print('from B')
    pass

class F(G):
    def test(self):
        print('from C')
    pass


class B(E):
    def test(self):
        print('from D')
    pass

class C(F):
    def test(self):
        print('from B')
    pass
class D(G):
    def test(self):
        print('from B')
    pass

class A(B,C,D): def test(self): print('from A') pass print(F.mro()) # 查詢順序 [<class '__main__.B'>, <class '__main__.E'>, <class '__main__.G'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class 'object'>] f1 = F() f1.test()

  

        

二、super()和mro列表的使用

    super()應用

     super()會返回一個特殊的物件,該物件會參考發起屬性查詢的那一個類的mro列表,依次去當前類的父類中查詢屬性。

    mor列表  

      mro()會顯示類的繼承順序,mor列表會按照從左到右開始查詢父類,直到找到第一個匹配這個屬性的類為止,類.mro()檢視mro列表

class B:
    def test(self):
        print('B---->test')


    def aaa(self):
        print('B---->aaa')

class A:
    def test(self):
        print('A---->test')
        super().test()



class C(A, B):
    def aaa(self):
        print('C----->aaa')


c = C()
c.test()  # 列印結果:  A---->test    B---->test
print(C.mro())

 

三、多型與多型性

    什麼是多型

      多型指的是一類事物有多種形態,(一個抽象類有多個子類,因而多型的概念依賴於繼承)

      例如動物的多種形態:人、狗、豬

      

# 多型:同一種事物的多種形態,動物分為人類,豬類(在定義角度)
# 方式1
class Animal:
    def run(self):
        raise Excecption('子類必須實現這個方法')


class People(Animal):
    def run(self):
        print('人正在走')


class Pig(Animal):
    def run(self):
        print('pig is walking')


class Dog(Animal):
    def run(self):
        print('dog is running')


peo = People()
pig = Pig()
d = Dog()

peo.run()
pig.run()
d.run()

  

# 方式2
import abc


class Animal(metaclass=abc.ABCMeta):  # 同一類事物:動物
    @abc.abstractmethod
    def talk(self):
        pass


class People(Animal):  # 動物的形態之一:人
    def talk(self):
        print('say hello')


class Dog(Animal):  # 動物的形態之二:狗
    def talk(self):
        print('say wangwang')


class Pig(Animal):  # 動物的形態之三:豬
    def talk(self):
        print('say aoao')

  

    什麼是多型性

      多型性是指具有不同功能的函式可以使用相同的函式名,這樣就可以用一個函式名呼叫不同內容的函式。在面向物件方法中一般是這樣表述多型性:向不同的物件傳送同一條訊息,不同的物件在接收       時會產生不同的行為(即方法)。也就是說,每個物件可以用自己的方式去響應共同的訊息。所謂訊息,就是呼叫函式,不同的行為就是指不同的實現,即執行不同的函式。

    

#多型性:一種呼叫方式,不同的執行效果(多型性)
def func(obj):
    obj.run()
 
func(peo1)
func(pig1)
func(d1)
 
 
# peo1.run()
# pig1.run()
 
 
# 多型性依賴於:繼承
##多型性:定義統一的介面,
def func(obj): #obj這個引數沒有型別限制,可以傳入不同型別的值
    obj.run() #呼叫的邏輯都一樣,執行的結果卻不一樣
 
func(peo1)
func(pig1)
 
func(d1)

    總結

      多型:同一種事物的多種形態,動物分為人類,豬類(在定義角度)多型性:一種呼叫方式,不同的執行效果(多型性)

三、為什麼要用多型性(多型性的好處)

  (1)增加了程式的靈活性
  以不變應萬變,不論物件千變萬化,使用者都是同一種形式去呼叫,如func(animal)
  

  (2)增加了程式額可擴充套件性
  通過繼承animal類建立了一個新的類,使用者無需更改自己的程式碼,還是用func(animal)去呼叫