面向對象之多繼承
阿新 • • 發佈:2017-11-13
多繼承
多繼承
Python不同版本的類
Python2.2之前類是沒有共同的祖先的,之後引入object類,它稱為新式類. Python2中為了兼容,分為舊式類(古典類)和新式類 Python3中全部都是新式類 新式類都是繼承自object的,新式類可以使用super.
多繼承
OCP原則: 多繼承、少修改 繼承的用途: 增強基類、實現多態 多態 在面向對象中,父類、子類通過繼承聯系在一起,如果通過同一個方法,實現了不同的表 現,就是多態.就相與不同的實例使用同一方法,得到的結果不同. 一個類繼承自多個類就是多繼承,它具備多個類的特征
多繼承的優缺點
優點: 多繼承能更好的模擬現實世界 缺點: 多繼承舍棄簡單,引入復雜性,帶來沖突 示例: 一個孩子繼承父母雙方的特征.那麽他的眼睛是像爸爸還是媽媽呢?像誰的多一點 呢? 多繼承的實現會導致編譯器設計的復雜度增加,所以現在很多語言也舍棄了類的多繼承 C++支持多繼承;Java舍棄了多繼承 Java中,一個類可以實現多個接口,一個接口也可以繼承多個接口.Java的接口很純粹, 只是方法的聲明,而讓繼承者來實現這些方法,於是具備了這些能力 多繼承可能會帶來二義性,例如,一個類繼承自貓和狗,貓和狗都有shout方法,那麽子類 是繼承誰的shout方法呢? 解決方案: 實現多繼承的語言,需要解決二義性,即繼承的規範,是深度優先還是廣度優先
Python多繼承實現
語法:
class 類名(基類列表):
語句塊
Python使用MRO(method resolusion order)解決基類搜索順序問題
需求: 為Document子類提供打印功能
思路:
1 在基類中提供print方法
基類提供的方法不應該具體實現,因為它未必適合子類的打印,子類中需要覆蓋重
寫,而且print算是一種能力–打印能力,不是所有的Document子類都需要.
2 在需要打印功能的子類上添加
如果直接在子類上增加,則違反了OCP原則,所以應該繼承後添加
# 第一種思路實現 class Document: def printable(self): print(‘Document‘) class Word(Document): def printable(self): print(‘word‘) class Pdf(Document): pass Word().printable() Pdf().printable()
# 第二種思路實現 class PrintableWord(Word): @classmethod def print(cls): # print = classmethod(print) print(id(print)) print(‘printword‘) class Document: def printable(self): print(‘Document‘) class Word(Document): pass class Pdf(Document): pass PrintableWord().print() print(PrintableWord.__dict__) print(PrintableWord.__mro__)
第二種思路的缺陷在在於,如果需要更多功能的實現,有些類需要,而有些類不需要, 使用此方法,則會寫很多類. 解決方案: 1. 可以使用裝飾器,寫一個功能就給一個類添加一個功能,不用此功能就取消裝飾器, 增添功能非常靈活 2. 使用Mixin,多繼承的思路,寫一個類,有需要添加的功能,在將此類和需要功能的類 組合在一起,也能解決此問題,並且類還可以繼承
# 裝飾器實現 # 裝飾器函數,給類添加打印功能的屬性 def printable(cls): cls.printable = lambda self: print(self.content) return cls class Document: def __init__(self,content): self.content = content class Word(Document): pass class Pdf(Document): pass @printable class PrintableWord(Word): pass PrintableWord(‘word print‘).printable() print(PrintableWord.__dict__) print(PrintableWord.__mro__)
# Mixin實現 # Mixin實現附加打印功能 class Document: def __init__(self,content): self.content = content class Word(Document): pass class Pdf(Document): pass class PrintableMixin: def print(self): print(self.content,‘ Mixin‘) class PrintableWord(PrintableMixin,Word): pass PrintableWord(‘word print‘).print() print(PrintableWord.__mro__) # 通過繼承Mixin,實現加強Mixin的打印功能 class SuperPrintableMixin(PrintableMixin): def print(self): print(‘strengthen‘) super().print() print(‘strengthen‘) class PrintableWord(SuperPrintableMixin,Word): pass PrintableWord(‘word print‘).print() print(PrintableWord.__mro__)
Mixin類
Mixin本質上就是多繼承的實現
Mixin體現的是一種組合的設計模式
在面向對象的設計中,一個復雜的類,往往需要很多功能,而這些功能都來自不同的類,
這就需要很多類組合在一起.
從設計模式的角度來說,多組合、少繼承
Mixin類的使用原則
1 Mixin類中不應該顯示的出現__init__初始化方法
2 Mixin類通常不能獨立工作,因為它的作用是混入別的類中來實現部分功能
3 Mixin類的祖先類也應該是Mixin類
使用時,Mixin類通常在繼承列表的第一個位置
例如class PrintableWord(PrintableWord,word):pass
組合的實現可以使用裝飾器或Mixin,如果要使用繼承的話,使用Mixin.
本文出自 “12064120” 博客,請務必保留此出處http://12074120.blog.51cto.com/12064120/1981086
面向對象之多繼承