天天看點

繼承進階

繼承進階

一、複習

面向對象

  1.類:具有相同屬性和方法 的一類事物

     類名可以執行個體化一個對象

     類名可以調用類屬性,(靜态屬性 和(方法)動态屬性)

  2.對象:也就是執行個體

        對象名:調用對象屬性

          調用方法

  3.什麼叫抽象?

    從小到大的過程

  4.組合-----什麼有什麼的關系(将一個類的對象當做另一個類的屬性)

  5.繼承-----什麼是什麼的關系

      從大範圍到小範圍的過程

      繼承的作用:減少代碼的重用性

      子類有的方法,就用子類的。不會調用父類的方法。

      如果要在子類中調用父類的方法:super().類名()

  6.派生:父類沒有的子類有了

      派生類:在父類的基礎上,又産生了子類,這個子類就叫做派生類

      派生屬性:父類裡沒有的屬性但子類中有了的屬性就叫做派生方法。

      派生方法:父類裡沒有的方法但子類中有了的方法就叫做派生方法。

  7.方法的重寫

      父類裡有子類裡也有的方法叫做方法的重寫

二、接口類與抽象類

1.接口類:(在抽象類的基礎上)

    在python中,預設是沒有接口類的

    接口類不能被執行個體化(如果執行個體化會報錯)

    接口類中的方法不能被實作

繼承進階
1 1.正常調用
 2 class Applepay:
 3     def pay(self,money):
 4         print('apple pay 支付了%s' %money)
 5 
 6 class Alipay:
 7     def pay(self,money):
 8         print('支付寶  支付了%s' %money)
 9 
10 def payment(pay_obj,money):  #執行個體化的另一種調用,這個方法讓執行個體化的時候按照payment調用:就像下面的payment(apple1,200)
11         pay_obj.pay(money)
12 
13 apple1 = Applepay()
14 # apple1.pay(200)
15 payment(apple1,200)      
繼承進階
繼承進階
1 # 2.有時候寫的時候會把方法寫錯,自己定義一個主動報錯
 2 # 接口初成:手動報異常:NotImplementedError來解決開發中遇到的問題
 3 class Payment:
 4     def pay(self):
 5         raise NotImplementedError  #主動讓程式報錯
 6 
 7 class Wechatpay(Payment): #微信支付
 8     def pay(self,money):
 9         print('微信支付了%s元',money)
10 
11 class QQchatpay(Payment): #QQ支付
12     def fuqian(self,money):
13         print('QQ支付了%s元',money)
14 
15 p = Wechatpay()
16 p.pay(200)   #不報錯
17 q = QQchatpay()   #不報錯
18 q.pay()  #報錯      
繼承進階
繼承進階
1 # 3.借用abc子產品來實作接口
 2 #接口類(就是為了提供标準,限制後面的子類)
 3 from abc import ABCMeta,abstractmethod
 4 class Payment(metaclass=ABCMeta):
 5     @abstractmethod
 6     def pay(self,money):
 7         pass
 8 
 9 class Wechatpay(Payment):
10     def fuqian(self,money):
11         '''實作了pay的功能,但是方法名字不一樣'''
12         print('微信支付了%s元'%money)
13 
14 class Alipay:
15     def pay(self,money):
16         print('支付寶  支付了%s' %money)
17 
18 # p = Wechatpay() #報錯了(因為上面定義了一個接口類,接口類裡面
19 # 定義了一個pay方法,而在下面的Wechatpay方法裡沒有pay方法,不能
20 # 調用,在接口類裡面限制一下,接口類裡的pay方法裡面不能寫其他,直接pass)
21 a = Alipay()
22 a.pay(200)
23 p = Payment() #接口類不能被執行個體化      
繼承進階
繼承進階
1 接口提取了一群類共同的函數,可以把接口當做一個函數的集合。
 2 
 3 然後讓子類去實作接口中的函數。
 4 
 5 這麼做的意義在于歸一化,什麼叫歸一化,就是隻要是基于同一個接口實作的類,那麼所有的這些類産生的對象在使用時,從用法上來說都一樣。
 6 
 7 歸一化,讓使用者無需關心對象的類是什麼,隻需要的知道這些對象都具備某些功能就可以了,這極大地降低了使用者的使用難度。
 8 
 9 比如:我們定義一個動物接口,接口裡定義了有跑、吃、呼吸等接口函數,這樣老鼠的類去實作了該接口,松鼠的類也去實作了該接口,由二者分别産生一隻老鼠和一隻松鼠送到你面前,即便是你分别不到底哪隻是什麼鼠你肯定知道他倆都會跑,都會吃,都能呼吸。
10 
11 再比如:我們有一個汽車接口,裡面定義了汽車所有的功能,然後由本田汽車的類,奧迪汽車的類,大衆汽車的類,他們都實作了汽車接口,這樣就好辦了,大家隻需要學會了怎麼開汽車,那麼無論是本田,還是奧迪,還是大衆我們都會開了,開的時候根本無需關心我開的是哪一類車,操作手法(函數調用)都一樣
12 
13 為何要用接口      
繼承進階

接口也就是做限制,讓下面的類的方法都按照接口類中給出的方法去定義。如果接口類裡面有的方法類裡面沒有,那麼那個類就不能被執行個體化。(字面了解)

繼承的第二種含義非常重要。它又叫“接口繼承”。

接口繼承實質上是要求“做出一個良好的抽象,這個抽象規定了一個相容接口,使得外部調用者無需關心具體細節,可一視同仁的處理實作了特定接口的所有對象”——這在程式設計上,叫做歸一化。

2.抽象類:

    在python中,預設是有的

    父類的方法,子類必須實作

    抽象類(父類)的方法可以被實作

繼承進階
1 # 抽象類
 2 # 什麼叫做抽象?  從小範圍到大範圍
 3 from abc import ABCMeta,abstractmethod
 4 class Animal(metaclass=ABCMeta):
 5     @abstractmethod
 6     def eat(self):
 7         print('打開糧食的袋子')
 8         print('放一個吃飯的碗')
 9         print('吧糧食倒在碗裡')
10 
11     @abstractmethod
12     def sleep(self):
13         pass
14 
15 class Dog(Animal):
16     #實作吃喝睡的方法
17     def eat(self):
18         super().eat()
19         # super(Dog, self).eat()
20         print('dog is eating')
21     def sleep(self):
22         print('dog is sleeping')
23 
24 # d = Dog()
25 # d.eat()
26 a = Animal()  #抽象類不能被執行個體化      
繼承進階

3.抽象類和接口類的差別:接口類不能實作方法,抽象類可以實作方法裡面的内容

4.抽象類和接口類的相同點:都是用來做限制的,都不能被執行個體化

5.抽象類和接口類的使用:

  當幾個子類的父類有相同的功能需要被實作的時候就用抽象類

  當幾個子類有相同的功能,但是實作各不相同的時候就用接口類

6.python中的抽象類和接口類在Java裡面的差別

  接口類支援多繼承

  抽象類隻支援單繼承

三、多繼承

在繼承抽象類的過程中,我們應該盡量避免多繼承;

而在繼承接口的時候,我們反而鼓勵你來多繼承接口

?

1

2

接口隔離原則:

使用多個專門的接口,而不是用單一的總接口。即用戶端不應該依賴那些不需要的接口

繼承進階
1 class A:
 2     def test(self):
 3         print('from A')
 4 class B(A):
 5     def test(self):
 6         print('from B')
 7 class C(A):
 8     def test(self):
 9         print('from C')
10 class D(A):
11     def test(self):
12         print('from D')
13 class E(B):pass
14     # def test(self):
15     #     print('from E')
16 
17 class F(E,D,C):pass
18     # def test(self):
19         # print('from F')
20 
21 
22 # b= B()
23 # b.test()
24 # d = D()
25 # d.test() #一級一級往上找,自己沒有,就繼承爹的,爹沒有就找爺爺的
26         # 再找不到就報錯了
27 f = F()
28 f.test()
29 print(F.mro()) #檢視找父類的順序      
繼承進階

四、鑽石繼承

新式類:廣度優先:橫着找(如鑽石繼承圖,誰先在前面就找誰)

經典類:深度優先:從上到下找

五、多态

多态指的是一類事物有多種形态(比如:老師.下課鈴響了(),學生.下課鈴響了(),老師執行的是下班操作,學生執行的是放學操作,雖然二者消息一樣,但是執行的效果不同)

 例如:動物有多種形态:人,狗,豬

繼承進階
1 from abc import ABCMeta,abstractmethod
 2 class Animal(metaclass=ABCMeta):
 3     @abstractmethod
 4     def eat(self):pass
 5 class Cat(Animal):  #動物的形态之一:貓
 6     def eat(self):
 7         print('cat eat')
 8 class Dog(Animal):  #動物的形态之二:狗
 9     def eat(self):
10         print('dog eat')
11 
12 class Pig(Animal):pass  #動物的形态之三:豬
13 def eat_fun(animal_obj): #定義一個函數讓這個函數名去調用
14     animal_obj.eat()
15 c = Cat()
16 eat_fun(c)  #函數名(對象)
17 
18 d = Dog() 
19 eat_fun(d)
20 
21 c = Cat()
22 c.eat()      
繼承進階

python自帶多态:

  多态:同一類事物的多種狀态

  python裡處處都是多态,隻是我們一般發現不了

  操作的時候不需要關心這個對象的資料類型,你隻要用就行了

靜态多态性(了解就好)

鴨子類型(如果兩個類裡面都有相同的方法,但是他們的類裡面沒有任何繼承)
    序列(str,list,tuple):有順序的資料集合,這三個沒有任何繼承      

一、複習

面向對象

  1.類:具有相同屬性和方法 的一類事物

     類名可以執行個體化一個對象

     類名可以調用類屬性,(靜态屬性 和(方法)動态屬性)

  2.對象:也就是執行個體

        對象名:調用對象屬性

          調用方法

  3.什麼叫抽象?

    從小到大的過程

  4.組合-----什麼有什麼的關系(将一個類的對象當做另一個類的屬性)

  5.繼承-----什麼是什麼的關系

      從大範圍到小範圍的過程

      繼承的作用:減少代碼的重用性

      子類有的方法,就用子類的。不會調用父類的方法。

      如果要在子類中調用父類的方法:super().類名()

  6.派生:父類沒有的子類有了

      派生類:在父類的基礎上,又産生了子類,這個子類就叫做派生類

      派生屬性:父類裡沒有的屬性但子類中有了的屬性就叫做派生方法。

      派生方法:父類裡沒有的方法但子類中有了的方法就叫做派生方法。

  7.方法的重寫

      父類裡有子類裡也有的方法叫做方法的重寫

二、接口類與抽象類

1.接口類:(在抽象類的基礎上)

    在python中,預設是沒有接口類的

    接口類不能被執行個體化(如果執行個體化會報錯)

    接口類中的方法不能被實作

繼承進階
1 1.正常調用
 2 class Applepay:
 3     def pay(self,money):
 4         print('apple pay 支付了%s' %money)
 5 
 6 class Alipay:
 7     def pay(self,money):
 8         print('支付寶  支付了%s' %money)
 9 
10 def payment(pay_obj,money):  #執行個體化的另一種調用,這個方法讓執行個體化的時候按照payment調用:就像下面的payment(apple1,200)
11         pay_obj.pay(money)
12 
13 apple1 = Applepay()
14 # apple1.pay(200)
15 payment(apple1,200)      
繼承進階
繼承進階
1 # 2.有時候寫的時候會把方法寫錯,自己定義一個主動報錯
 2 # 接口初成:手動報異常:NotImplementedError來解決開發中遇到的問題
 3 class Payment:
 4     def pay(self):
 5         raise NotImplementedError  #主動讓程式報錯
 6 
 7 class Wechatpay(Payment): #微信支付
 8     def pay(self,money):
 9         print('微信支付了%s元',money)
10 
11 class QQchatpay(Payment): #QQ支付
12     def fuqian(self,money):
13         print('QQ支付了%s元',money)
14 
15 p = Wechatpay()
16 p.pay(200)   #不報錯
17 q = QQchatpay()   #不報錯
18 q.pay()  #報錯      
繼承進階
繼承進階
1 # 3.借用abc子產品來實作接口
 2 #接口類(就是為了提供标準,限制後面的子類)
 3 from abc import ABCMeta,abstractmethod
 4 class Payment(metaclass=ABCMeta):
 5     @abstractmethod
 6     def pay(self,money):
 7         pass
 8 
 9 class Wechatpay(Payment):
10     def fuqian(self,money):
11         '''實作了pay的功能,但是方法名字不一樣'''
12         print('微信支付了%s元'%money)
13 
14 class Alipay:
15     def pay(self,money):
16         print('支付寶  支付了%s' %money)
17 
18 # p = Wechatpay() #報錯了(因為上面定義了一個接口類,接口類裡面
19 # 定義了一個pay方法,而在下面的Wechatpay方法裡沒有pay方法,不能
20 # 調用,在接口類裡面限制一下,接口類裡的pay方法裡面不能寫其他,直接pass)
21 a = Alipay()
22 a.pay(200)
23 p = Payment() #接口類不能被執行個體化      
繼承進階
繼承進階
1 接口提取了一群類共同的函數,可以把接口當做一個函數的集合。
 2 
 3 然後讓子類去實作接口中的函數。
 4 
 5 這麼做的意義在于歸一化,什麼叫歸一化,就是隻要是基于同一個接口實作的類,那麼所有的這些類産生的對象在使用時,從用法上來說都一樣。
 6 
 7 歸一化,讓使用者無需關心對象的類是什麼,隻需要的知道這些對象都具備某些功能就可以了,這極大地降低了使用者的使用難度。
 8 
 9 比如:我們定義一個動物接口,接口裡定義了有跑、吃、呼吸等接口函數,這樣老鼠的類去實作了該接口,松鼠的類也去實作了該接口,由二者分别産生一隻老鼠和一隻松鼠送到你面前,即便是你分别不到底哪隻是什麼鼠你肯定知道他倆都會跑,都會吃,都能呼吸。
10 
11 再比如:我們有一個汽車接口,裡面定義了汽車所有的功能,然後由本田汽車的類,奧迪汽車的類,大衆汽車的類,他們都實作了汽車接口,這樣就好辦了,大家隻需要學會了怎麼開汽車,那麼無論是本田,還是奧迪,還是大衆我們都會開了,開的時候根本無需關心我開的是哪一類車,操作手法(函數調用)都一樣
12 
13 為何要用接口      
繼承進階

接口也就是做限制,讓下面的類的方法都按照接口類中給出的方法去定義。如果接口類裡面有的方法類裡面沒有,那麼那個類就不能被執行個體化。(字面了解)

繼承的第二種含義非常重要。它又叫“接口繼承”。

接口繼承實質上是要求“做出一個良好的抽象,這個抽象規定了一個相容接口,使得外部調用者無需關心具體細節,可一視同仁的處理實作了特定接口的所有對象”——這在程式設計上,叫做歸一化。

2.抽象類:

    在python中,預設是有的

    父類的方法,子類必須實作

    抽象類(父類)的方法可以被實作

繼承進階
1 # 抽象類
 2 # 什麼叫做抽象?  從小範圍到大範圍
 3 from abc import ABCMeta,abstractmethod
 4 class Animal(metaclass=ABCMeta):
 5     @abstractmethod
 6     def eat(self):
 7         print('打開糧食的袋子')
 8         print('放一個吃飯的碗')
 9         print('吧糧食倒在碗裡')
10 
11     @abstractmethod
12     def sleep(self):
13         pass
14 
15 class Dog(Animal):
16     #實作吃喝睡的方法
17     def eat(self):
18         super().eat()
19         # super(Dog, self).eat()
20         print('dog is eating')
21     def sleep(self):
22         print('dog is sleeping')
23 
24 # d = Dog()
25 # d.eat()
26 a = Animal()  #抽象類不能被執行個體化      
繼承進階

3.抽象類和接口類的差別:接口類不能實作方法,抽象類可以實作方法裡面的内容

4.抽象類和接口類的相同點:都是用來做限制的,都不能被執行個體化

5.抽象類和接口類的使用:

  當幾個子類的父類有相同的功能需要被實作的時候就用抽象類

  當幾個子類有相同的功能,但是實作各不相同的時候就用接口類

6.python中的抽象類和接口類在Java裡面的差別

  接口類支援多繼承

  抽象類隻支援單繼承

三、多繼承

在繼承抽象類的過程中,我們應該盡量避免多繼承;

而在繼承接口的時候,我們反而鼓勵你來多繼承接口

?

1

2

接口隔離原則:

使用多個專門的接口,而不是用單一的總接口。即用戶端不應該依賴那些不需要的接口

繼承進階
1 class A:
 2     def test(self):
 3         print('from A')
 4 class B(A):
 5     def test(self):
 6         print('from B')
 7 class C(A):
 8     def test(self):
 9         print('from C')
10 class D(A):
11     def test(self):
12         print('from D')
13 class E(B):pass
14     # def test(self):
15     #     print('from E')
16 
17 class F(E,D,C):pass
18     # def test(self):
19         # print('from F')
20 
21 
22 # b= B()
23 # b.test()
24 # d = D()
25 # d.test() #一級一級往上找,自己沒有,就繼承爹的,爹沒有就找爺爺的
26         # 再找不到就報錯了
27 f = F()
28 f.test()
29 print(F.mro()) #檢視找父類的順序      
繼承進階

四、鑽石繼承

新式類:廣度優先:橫着找(如鑽石繼承圖,誰先在前面就找誰)

經典類:深度優先:從上到下找

五、多态

多态指的是一類事物有多種形态(比如:老師.下課鈴響了(),學生.下課鈴響了(),老師執行的是下班操作,學生執行的是放學操作,雖然二者消息一樣,但是執行的效果不同)

 例如:動物有多種形态:人,狗,豬

繼承進階
1 from abc import ABCMeta,abstractmethod
 2 class Animal(metaclass=ABCMeta):
 3     @abstractmethod
 4     def eat(self):pass
 5 class Cat(Animal):  #動物的形态之一:貓
 6     def eat(self):
 7         print('cat eat')
 8 class Dog(Animal):  #動物的形态之二:狗
 9     def eat(self):
10         print('dog eat')
11 
12 class Pig(Animal):pass  #動物的形态之三:豬
13 def eat_fun(animal_obj): #定義一個函數讓這個函數名去調用
14     animal_obj.eat()
15 c = Cat()
16 eat_fun(c)  #函數名(對象)
17 
18 d = Dog() 
19 eat_fun(d)
20 
21 c = Cat()
22 c.eat()      
繼承進階

python自帶多态:

  多态:同一類事物的多種狀态

  python裡處處都是多态,隻是我們一般發現不了

  操作的時候不需要關心這個對象的資料類型,你隻要用就行了

靜态多态性(了解就好)

鴨子類型(如果兩個類裡面都有相同的方法,但是他們的類裡面沒有任何繼承)
    序列(str,list,tuple):有順序的資料集合,這三個沒有任何繼承