python學習筆記:第17天 面向對象
- 2020 年 1 月 20 日
- 筆記
一、類與類之間的依賴關係
⼤千世界, 萬物之間皆有規則和規律. 我們的類和對象是對⼤千世界中的所有事物進⾏歸類. 那事物之間存在著相對應的關係. 類與類之間也同樣如此. 在⾯向對象的世界中. 類與類 中存在以下關係:
- 依賴關係
- 關聯關係
- 組合關係
- 聚合關係
- 繼承關係
- 實現關係
依賴關係
可以簡單的理解,就是一個類A使用到了另一個類B,而這種使用關係是具有偶然性的、臨時性的、非常弱的,但是B類的變化會影響到A。表現在程式碼層面,類A當中使用了類B,其中類B是作為類A的方法參數、方法中的局部變數、或者靜態方法調用。注意,要避免雙向依賴。一般來說,不應該存在雙向依賴。

class Person: def eat(self, food): print(f'我要吃{food.name}') def read(self, book): print(f'我在看{book.book_name}') class Food: def __init__(self, name): self.name = name class Book: def __init__(self, book_name): self.book_name = book_name apple = Food('蘋果') book = Book('紅樓夢') p = Person() p.eat(apple) # apple對象以方法參數的形式傳入到p對象中使用 p.read(book) # 可以說是Person類是依賴於Food類和Book類 # 執行結果: # 我要吃蘋果 # 我在看紅樓夢
關聯關係.組合關係, 聚合關係
其實這三個在程式碼上寫法是⼀樣的. 但是, 從含義上是不⼀樣的.
- 關聯關係. 兩種事物必須是互相關聯的. 但是在某些特殊情況下是可以更改和更換的.
- 聚合關係. 屬於關聯關係中的⼀種特例. 側重點是xxx和xxx聚合成xxx. 各⾃有各⾃的聲明周期. 比如電腦. 電腦⾥有CPU, 硬碟, 記憶體等等. 電腦掛了. CPU還是好的. 還是完整的個體
- 組合關係. 屬於關聯關係中的⼀種特例. 寫法上差不多. 組合關係比聚合還要緊密. 比如⼈的⼤腦, ⼼臟, 各個器官. 這些器官組合成⼀個⼈. 這時. ⼈如果掛了. 其他的東⻄也跟著掛了.

我們來看一個例子:
class Boy: def __init__(self, name, grilFriend): self.name = name self.grilFriend = grilFriend # grilFriend參數以變數的形式存儲在Boy類中,這就形成了關聯關係 def sendGift(self): print(f'送給女朋友{self.grilFriend.name}一個禮物') class Girl: def __init__(self, name): self.name = name girl = Girl('小麻煩') boy = Boy('馬臉', girl) # 此時在Boy對象初始化時把Girl對象當作傳參數出入類中 boy.sendGift() # 運行結果: # 送給女朋友小麻煩一個禮物
上面例子就是一個關聯關係,一般男女朋友都是固定的,不可能經常更換;Girl對象作為Boy的變數存在與Boy類中,如果缺失這個屬性,Boy類可能無法正常工作。其實這樣的關係在生活中還有很多,比如說學生和老師:
# 老師和學生的關係,一對多的關係 反過來就是一對一 class Tearcher: def __init__(self, name, stuList=None): self.name = name if stuList: self.stuList = stuList else: self.stuList = [] def addStudent(self, student): self.stuList.append(student) def showStudent(self): for stu in self.stuList: print(stu.id, stu.name, stu.teacher) class Student: def __init__(self, sid, name, teacher=None): self.id = sid self.name = name if teacher: self.teacher = teacher.name else: self.teacher = None t = Tearcher('大張偉') s1 = Student(1, '郭德綱') s2 = Student(2, '小瀋陽', t) s3 = Student(3, '宋小寶') s4 = Student(4, '岳雲鵬', t) t.addStudent(s1) t.addStudent(s2) t.addStudent(s3) t.addStudent(s4) t.showStudent() # 運行結果: # 1 郭德綱 None # 2 小瀋陽 大張偉 # 3 宋小寶 None # 4 岳雲鵬 大張偉
一個老師可以有多個學生,這就是一對多的關係了;如果反過來,一個學生只有一個老師,那就是一對一的關係,好了. 這就是關聯關係。當我們在邏輯上出現了:我需要你,你還得屬於我,這種邏輯就是關聯關係,那注意這種關係的緊密程度比上⾯的依賴關係要緊密的多
- 組合關係和聚合關係. 其實程式碼上的差別不⼤. 都是把另⼀個類的對象作為這個類的屬性來傳遞和保存. 只是在含義上會有些許的不同⽽已
- 繼承關係和實現關係的內容後期再學習到繼承的時候再補上
二、類中的特殊成員
什麼是特殊成員呢?__init_()
就是⼀個特殊的成員. 說⽩了. 帶雙下劃線的那⼀坨. 這些⽅ 法在特殊的場景的時候會被⾃動的執⾏。比如:
__init__() # 使用 class_name() 會自動執行初始化函數__init__() __call__() # 使用 instance() 會自動執行__call__() __getitem__() # 執行 instance[key] 時會⾃動觸發 __setitem__() # 執⾏ instance[key] = value 時會⾃動觸發 __delitem__() # 執⾏del instance[key] 時會⾃動觸發 __add__() # 當執行 instance1 + instance2 時會自動觸發 __enter__() # 當執行with instance 時會觸發,先執行__enter__函數 __exit__() # 執行完with語句退出時執行(with open ...) __str__() # 列印一個對象時返回的時對象的__str__方法 __repr__() # 與repr差不多,返回的格式更為正式(比較偏底層,接近解釋器) __hash__ = None # 設置對象為不可hash __hash__() # 自己訂製hash計算方法 __len__() # len()調用的就是__len__ __gt__() # 大於或等於 __ge__() # 大於 __lt__() # 小於或等於 __le__() # 小於 __eq__() # 等於