第二十三章:面向对象(3)
1.繼承的另一種使用方式?? *****
最常見的是直接繼承一個已經存在的類
當你想要創建一個新的類 發現這個類中的一些 在某一個類中已經存在
那就沒有必要從頭開始寫 ,可以直接繼承已有的類 然后做補充
?
注意注意::::::
?
?
class MyList(list):? ?def __init__(self,element_cls):
? ? ? ?# 當你覆蓋了init方法時
? ? ? ?# 不要忘記調用super().init函數讓父類完成原有的初始化操作
? ? ? ?super().__init__()
? ? ? ?self.element_cls = element_cls
?
? ? ? ?
? ?def append(self, object):
? ? ? ?# if isinstance(object,str)
? ? ? ?if object.__class__ == self.element_cls:
? ? ? ? ? ?super().append(object)
? ? ? ?else:
? ? ? ? ? ?print("只能存儲%s類型!" % self.element_cls.__name__)
? ? ? ? ? ?
?
2.super()的問題? mro列表?
python支持多繼承? 一個類可以同時繼承多個父類
好處是更加靈活
問題是:屬性的查找順序該怎么確定
# 問題:多繼承時如果多個父類中出現了同名的屬性/函數# 你不能用眼睛去判斷查找順序 ,需要使用mro列表來查看真正的繼承順序
# 總結:super在訪問父類屬性時 是按照mro列表一層層往上找的
?
#測試
class A:
? ?def test(self):
? ? ? ?print("from A")
? ? ? ?super().test() # 應該報錯..... 但是卻執行成功了
class B:
? ?def test(self):
? ? ? ?print("from B")
? ?pass
?
class C(A,B):
? ?pass
?
c = C()
c.test()
?
#最后:盡量不要使用多繼承
組合:
"""組合:
指的是 一個類把另一個類的對象作為自己的屬性 就稱之為組合
無處不在
當你定義一個類 并且這個類擁有某種類型的屬性時 就稱之為組合
?
都是用用來重用代碼的方式:
組合描述的是 什么擁有什么的關系 ? 學生 有 書 學生有手機
基礎描述的是 什么是什么的關系 ? ? 麥兜是豬 ? 豬豬俠也是豬
"""
?
?
# class Person:
# ? ? def __init__(self,name):
# ? ? ? ? self.name = name
#
#
# p = Person("rose")
# print(p.name)
?
?
class PC:
? ?def open_app(self,app_name):
? ? ? ?print("open %s" % app_name)
?
class OldBoyStudent:
? ?def __init__(self,PC,notebook):
? ? ? ?self.PC = PC
? ? ? ?self.notebook = notebook
? ?pass
?
pc = PC()
notebook = PC()
?
?
stu = OldBoyStudent(pc,notebook)
3.菱形繼承問題? ***
?
新式類與經典類
# 在py2中 A就是一個經典類# class A:
# ? ? pass
?
# 如果你的代碼需要兼容py2 那應該顯式的繼承object 無論是直接還是間接繼承
class B(object):
? ?pass
?
class A(B):
? ?pass
?
?
?
多層菱形繼承
?
class A:? ?# a = 1
? ?pass
?
class B(A):
? ?# a = 2
? ?pass
?
class C(A):
? ?# a = 3
? ?pass
?
class D(A):
? ?# a = 4
? ?pass
?
class E(B,C,D):
? ?# a = 5
? ?pass
?
e1 = E()
# print(e1.a)
# 新式類的順序
# E B C D A object
# 經典類的順序
# E B A C D
# print(E.mro())
?
注意:經典類沒有mro列表
?
4.接口 ***
接口是什么
例如USB??
電腦內部具備USB相應的功能 如果要使用的話?? 就必須給外界提供一個使用方式,該方式就稱之為接口 ,
在程序中功能通常是用函數來表示, 對于外界而言 無需清楚函數時如何實現的 只要知道函數名即可, 這個函數名稱就可以稱之為接口?
外界調用接口就能完成某個任務
接口其實就是一組功能的定義,但是只清楚函數名稱,而沒有具體的實現細節
相當于是一套規范,
例如USB?? 規定了接口的外觀,大小,以及每條線路的功能是什么
硬件開發商照著這個USB協議來生產設備,就可以被電腦使用
class USB:?
? ?def open(self):
? ? ? ?pass
?
? ?def close(self):
? ? ? ?pass
?
? ?def work(self):
? ? ? ?pass
好處:
使用接口可以提高程序的擴展性
只要對象按照接口規定方法來實現,使用者就可以無差別使用所有對象
接口與抽象類
抽象:
指的是 不清楚 不具體 看不懂
抽象方法:
指的是 沒有函數體的方法?? 用@abc.abstractmethod 裝飾器
如果類中具備抽象方法 那么這個類就稱之為抽象類
抽象類的特點:
不能直接實例化? 必須有子類覆蓋了所有抽象方法后才能實例化子類
與接口的區別:
接口是指只有方法聲明而沒有實現體 ,? 接口中所有方法都是抽象的
import abc?
class Test(metaclass=abc.ABCMeta):
?
? ?
?
問題:如果接口的子類沒有實現接口中的方法,那是沒有任何意義的
抽象類之所以出現的意義:通過抽象類來強行限制子類必須覆蓋所有的抽象方法
?
鴨子類型
說如果一個對象叫聲像鴨子,走路像鴨子,長得像鴨子,那它就是鴨子
是python 推薦的方式,python不喜歡強行限制你
?class PC():
?
? ?def conntent_device(self, usb_device):
? ? ? ?usb_device.open()
? ? ? ?usb_device.work()
? ? ? ?usb_device.close()
?
class Mouse:
? ?# 實現接口規定的所有功能
? ?def open(self):
? ? ? ?print("mouse opened")
?
? ?def work(self):
? ? ? ?print("mouse working...")
?
? ?def close(self):
? ? ? ?print("mouse closed")
?
mouse = Mouse()
pc = PC()
?
pc.conntent_device(mouse)
?
?
?
class KeyBoard:
? ?def open(self):
? ? ? ?print("KeyBoard opened")
?
? ?def work(self):
? ? ? ?print("KeyBoard working...")
?
? ?def close(self):
? ? ? ?print("KeyBoard closed")
?
key1 = KeyBoard()
?
# 如果key1的特征和行為都像USB設備 那就把它當做USB設備來使用
# 對于使用者而言可以不用關心這個對象是什么類,是如如何是實現,
pc.conntent_device(key1)
?
?
案例2:
class Linux:? ?def read_data(self,device):
? ? ? ?data = device.read()
? ? ? ?return data
?
? ?def write_data(self,device,data):
? ? ? ?device.write(data)
?
class Disk:
? ?def read(self):
? ? ? ?print("disk reading....")
? ? ? ?return "這是一個磁盤上的數據"
?
? ?def write(self,data):
? ? ? ?print("disk writing %s..." % data)
?
class UP:
? ?def read(self):
? ? ? ?print("disk reading....")
? ? ? ?return "這是一個U盤上的數據"
?
? ?def write(self,data):
? ? ? ?print("disk writing %s..." % data)
?
?
l = Linux()
?
d = Disk()
data = l.read_data(d)
l.write_data(d,"這是一個數據....")
?
?
up1 = UP()
l.read_data(up1)
l.write_data(up1,"一個數據...")
例如linux 有一句話叫一切皆文件
之所以這么設計是為了提高擴展性,讓Linux可以無差別對待任何設備!
?
?
?
今日的知識點:
1.繼承的另一種使用方法
繼承一個已經存在的類 并擴展新方法? 或修改原來的方法
2.super() 是按照mro列表來查找屬性的
3.組合? 一個類把另一個類的對象作為屬性
菱形繼承的問題
?
經典類:不是object的子類?? 僅在py2中出現
深度優先
新式類:object的子類 py3中都是新式類
先深度 直到有一個公共父類時,查找其他路線(基于C3算法)
5.接口是一套協議規范,具體表現:一堆只有方法聲明而沒有實現體的方法?
6.抽象類:具備抽象方法的類? 抽象方法時沒有實現體的方法?? 不能直接實例化? 通過abc模塊來實現
抽象類既可以以后抽象方法也可以有普通方法
而接口中全都是抽象方法?
接口的出現是為了提高擴展性,抽象類是為類限制子類必須按照接口要求的來實現
鴨子類型
對于一個優秀的程序員,即時沒有接口和抽象類的限制,也能寫出一個具備擴展性的程序
就如何做到:鴨子類型?
鴨子類型:這個對象 長的想鴨子 叫聲像鴨子 走路像鴨子? 那它就是鴨子
就可以把它當成鴨子來使用
?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/haojunliancheng/p/10882002.html
總結
以上是生活随笔為你收集整理的第二十三章:面向对象(3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html漂浮图片代码关闭,带关闭功能的漂
- 下一篇: 电脑任务栏消失解决办法