div不继承父类样式_Python编程思想(27):类的继承
生活随笔
收集整理的這篇文章主要介紹了
div不继承父类样式_Python编程思想(27):类的继承
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
-----------支持作者請轉發本文-----------李寧老師已經在「極客起源」 微信公眾號推出《Python編程思想》電子書,囊括了Python的核心技術,以及Python的主要函數庫的使用方法。讀者可以在「極客起源」 公眾號中輸入?160442?開始學習。-----------正文-----------繼承是面向對象的3大特征之一(另兩個特性是封裝和組合),也是實現軟件復用的重要手段。Python的繼承是多繼承機制,也就是一個子類可以同時有多個直接父類。1. ?繼承的語法Python子類繼承父類的語法是在定義子類時,將多個父類放在子類之后的圓括號中。語法格式如下:class SubClass(SuperClassl, SuperClass2,..) # 類定義部分從上面的語法格式來看,定義子類的語法非常簡單,只需在原來的類定義后增加圓括號,并在圓括號中添加多個父類,即可表明該子類繼承了這些父類。如果在定義一個 Python類時并未顯式指定這個類的直接父類,則這個類默認繼承 object類。因此,object類是所有類的父類,要么是其直接父類,要么是其間接父類。實現繼承的類被稱為子類,被繼承的類被稱為父類,也被稱為基類、超類。父類和子類的關系是一般和特殊的關系。例如水果和香蕉的關系,香蕉繼承了水果,香蕉是水果的子類,則香蕉是種特殊的水果。由于子類是一種特殊的父類,因此父類包含的范圍總比子類包含的范圍要大,所以可以認為父類是大類,而子類是小類。從實際意義上看,子類是對父類的擴展,子類是一種特殊的父類。從這個意義上看,使用繼承來描述子類和父類的關系是不準確的,用擴展更恰當。因此,這樣的說法更加準確:Banana類擴展了Fruit類。從子類的角度來看,子類擴展( extend)了父類,但從父類的角度來看,父類派生(derive)出子類。也就是說,擴展和派生所描述的是同一個動作,只是觀察角度不同而已。下面程序示范了子類繼承父類的特點。下面是 Fruit類的代碼。示例代碼:inherit.pyclass Fruit: def info(self): print(f"我是水果!重{self.weight}克" )class Food: def taste(self): print("不同食物的口感不同")# 定義Banana類,繼承了Fruit和Food類class Banana(Fruit, Food): pass# 創建Banana對象b = Banana()b.weight = 16# 調用Banana對象的info()方法b.info()# 調用Banana對象的taste()方法b.taste()這段代碼開始定義了兩個父類:Fruit類和Food類,接下來程序定義了一個 Banana類,該 Banana類是一個空類。在主程序部分,主程序創建了 Banana對象之后,可以訪問Banana對象的info()和 taste()方法,這表明 Banana對象也具有了info和 taste方法,這就是繼承的作用:子類擴展(繼承)了父類。在子類中將可以繼承得到父類定義的方法,這樣子類就可復用父類的方法了。2. ?關于多繼承大部分面向對象的編程語言(除了C++)都只支持單繼承,而不支持多繼承,這是由于多繼承不僅增加了編程的復雜度,而且很容易導致一些莫名的錯誤。Python雖然在語法上明確支持多繼承,但建議如果不是很有必要,則盡量不要使用多繼承,而是使用單繼承,這樣可以保證編程思路更清晰,而且可以避免很多麻煩。當一個子類有多個直接父類時,該子類會繼承得到所有父類的方法,這一點在前面代碼中已經演示了。現在的問題是,如果多個父類中包含了同名的方法,此時會發生什么呢?此時排在前面的父類中的方法會“遮蔽”排在后面的父類中的同名方法。示例代碼:multiple_inherit.pyclass Item: def info (self): print("Item中方法:", '這是一個商品') class Product: def info (self): print("Product中方法:", '這是一個移動產品')class Mouse1(Item, Product): passclass Mouse2(Product, Item): passm1 = Mouse1()m1.info()m2 = Mouse2()m2.info()在這段代碼中讓 Mouse1繼承了Item類和 Product類,Mouse2繼承了Product類和Item類,這兩個類的父類繼承順序是相反的。由于Mouse1類的Item排在前面,因此Item中定義的方法優先級更高, Python會優先到Item父類中搜尋方法,一旦在Item父類中搜尋到目標方法,Python就不會繼續向下搜尋了。上面程序中Item和 Product兩個父類中都包含了info()方法,當 Mouse1子類對象調用info方法時,子類中沒有定義info方法,因此 Python會從父類中尋找info方法,此時優先使用第1個父類Item中的info方法。而Mouse2子類對象調用的info()方法屬于Product類。運行上面程序,將看到如下輸出結果:Item中方法: 這是一個商品 Product中方法: 這是一個移動產品3. 重寫父類的方法子類擴展了父類,子類是一種特殊的父類。大部分時候,子類總是以父類為基礎,額外增加新的方法。但有一種情況例外:子類需要重寫父類的方法。例如鳥類都包含了飛翔方法,其中鴕鳥是種特殊的鳥類,因此鴕鳥應該是鳥的子類,它也將從鳥類獲得飛翔方法,但這個飛翔方法明顯不適合鴕鳥,因此,鴕鳥需要重寫鳥類的方法。示例代碼:override.pyclass Bird: # Bird類的fly()方法 def fly(self): print("我在天空里自由自在地飛翔...")class Ostrich(Bird): # 重寫Bird類的fly()方法 def fly(self): print("我只能在地上奔跑...") # 創建Ostrich對象os = Ostrich()# 執行Ostrich對象的fly()方法,將輸出"我只能在地上奔跑..."os.fly()運行上面程序,將看到運行os.fly()時執行的不再是Bird類的fly()方法,而是 Ostrich類的fly()方法。這種子類包含與父類同名的方法的現象被稱為方法重寫(Override),也被稱為方法覆蓋。可以說子類重寫了父類的方法,也可以說子類覆蓋了父類的方法。4. 使用未綁定方法調用被重寫的方法如果在子類中調用重寫之后的方法,Python總是會執行子類重寫的方法,不會執行父類中被重寫的方法。如果需要在子類中調用父類中被重寫的實例方法,那該怎么辦呢?讀者別忘了,Python類相當于類空間,因此 Python類中的方法本質上相當于類空間內的函數。所以,即使是實例方法,Python也允許通過類名調用。區別在于,在通過類名調用實例方法時,Python不會為實例方法的第1個參數self自動綁定參數值,而是需要程序顯式綁定第一個參數self。示例代碼:invoke_parent. pyclass BaseClass: def name (self): print('父類中定義的name方法')class SubClass(BaseClass): # 重寫父類的name方法 def name (self): print('子類重寫父類中的name方法') def process (self): print('執行process方法') # 直接執行name方法,將會調用子類重寫之后的name()方法 self.name() # 使用類名調用實例方法調用父類被重寫的方法 BaseClass.name(self)sc = SubClass()sc.process()上面程序中 SubClass繼承了 BaseClass類,并重寫了父類的name()方法。接下來程序在 SubClass類中定義了process()方法,該方法直接通過self調用name方法, Python將會執行子類重寫之后的name方法。后面的代碼通過顯式調用 Base_Class 中的name方法,并顯式為第1個參數self綁定參數值,這就實現了調用父類中被重寫的方法。5. ?使用 super函數調用父類的構造方法Python的子類也會繼承得到父類的構造方法,如果子類有多個直接父類,那么排在前面的父類的構造方法會被優先使用。例如如下代碼:示例代碼: super:pyclass Employee : def __init__ (self, salary): self.salary = salary def work (self): print('普通員工正在寫代碼,工資是:', self.salary)class Customer: def __init__ (self, favorite, address): self.favorite = favorite self.address = address def info (self): print(f'我是一個顧客,我的愛好是: {self.favorite},地址是{self.address}' )class Manager1 (Employee,Customer): passclass Manager2 (Customer, Employee): passm1 = Manager1(1235)m1.work()m2 = Manager2('服務器', '北京')m2.info()上面程序中定義了 Manager1類,該類繼承了 Employee和 Customer兩個父類。接下來程序中的Manager類將會優先使用 Employee類的構造方法(因為它排在前面),所以程序使用Manager(1235)來創建 Manager1對象。該構造方法只會初始化 salary實例變量,因此執行上面程序是沒有任何問題的。但如果為Manager2傳遞一個數值就會引發錯誤,因為Manager2使用了Customer的構造方法,因此應該使用Manager2('服務器', '北京')創建Manager2對象。為了讓 Manager能同時初始化兩個父類中的實例變量,Manager應該定義自己的構造方法就是重寫父類的構造方法。Python要求:如果子類重寫了父類的構造方法,那么子類的構造方法必須調用父類的構造方法。子類的構造方法調用父類的構造方法有兩種方式。
使用未綁定方法,這種方式很容易理解。因為構造方法也是實例方法。當然可以通過這種方式來調用;
使用supe()函數調用父類的構造方法;
總結
以上是生活随笔為你收集整理的div不继承父类样式_Python编程思想(27):类的继承的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果忘记开机密码_苹果电脑忘记开机密码快
- 下一篇: mysql索引使增删变慢_mysql优化