繼承進階 繼承進階
一、複習
面向物件
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):有順序的資料集合,這三個沒有任何繼承