19.面向物件-繼承與多型
阿新 • • 發佈:2020-12-16
面向物件的繼承與多型
1.繼承
繼承 : 一個類除了自身擁有的屬性方法外,還獲取了另一個類的屬性方法
被繼承的是父類(基類,超類)
繼承的是子類(衍生類)
繼承種類:
1.單繼承
2.多繼承
python中所有類的父類是 object
1.1 單繼承
# 單繼承 """ 子類只能繼承父類的公有成員,不能繼承私有成員 在繼承的環境中,物件的調取順序: 物件中->自己類中->父類中 都沒有報錯 """ class Human(): person="遠古人類" __mimi="未解之謎" def drink(self): print("茹毛飲血") def __eat(self): print("吃的是烤肉") class Man(Human):#繼承父類 def siyou(self): self.__eat() def drink(self): print("現代人喝飲料") obj = Man() # 1.子類可以使用父類的公有成員 print(obj.person) #遠古人類 # 2.子類不能使用父類的私有成員 """ obj.siyou() #報錯 : 'Man' object has no attribute '_Man__eat' """ # 3.子類可以重寫父類的公有成員 obj.drink() #現代人喝飲料
1.2 多繼承
""" 多繼承的弊端 : 會造成菱形繼承這種情況,理不清呼叫順序 super()物件會按照 mro 列表的順序依次呼叫,解決菱形繼承存在的問題 類名.mro() 返回列表 1.super 本身是一個類,super()是一個物件,用於掉用父類的繫結方法 2.super 只應用在繫結方法中,預設自動傳遞self引數(前提: super所在作用域存在self) 3.super作用 : 用於解決複雜的多繼承呼叫順序 經典類: 深度優先(python2.x) 新式類: 廣度優先(python3.x)->橫著遍歷一級父類,二級父類...到最後父類 寫多繼承時,儘量避免造成不同類相同方法名的情況,提高程式碼質量 ,高內聚,低耦合 高內聚: 一個模組只完成一個任務,專一性高 低耦合: 模組與模組之間可以彼此獨立不衝突,方便移植複用 """ # 1.多繼承 class Father(): pty="摳腳大叔" def hobby(self): print("打球") class Mother(): pty="貌美如花" def hobby(self): print("刷韓劇") class Son(Father,Mother): #繼承父類 pty="三好學生" def hobby(self): print("LOL") # 1.使用類呼叫類中成員 def lei(self): print(Mother.pty) Father.hobby(self) #注意引數別忘寫 # 2.使用物件呼叫類中成員 """物件呼叫順序 : 物件成員->自己類成員->父類成員""" def duixiang(self): print(self.pty) self.hobby() # 3.使用super呼叫父類中成員 """繫結方法 : 會自動把作用域self物件當成引數進行傳遞""" def sup(self): print(super().pty) #多個父類成員一樣,找第一個繼承的父類 super().hobby() obj = Son() obj.lei() #貌美如花,打球 obj.duixiang() #三好學生 LOL obj.sup() #摳腳大叔,打球 # 2.菱形繼承(鑽石繼承) class Human(): pty=4 def feel(self): print("天熱,脫1") print(self.pty) print("天冷,穿虎皮2") class Man(Human): pty=3 def feel(self): print("天熱了,光膀子3") super().feel() print("天冷了,穿羽絨服4") class Woman(Human): pty=2 def feel(self): print("天熱了,脫衣服5") super().feel() print("天冷了,穿羽絨服6") class Son(Man,Woman): pty=1 def feel(self): print("天熱了,光屁股7") super().feel() print("天冷了,穿棉襖8") obj = Son() obj.feel() """ 天熱了,光屁股7 天熱了,光膀子3 天熱了,脫衣服5 天熱,脫1 1 天冷,穿虎皮2 天冷了,穿羽絨服6 天冷了,穿羽絨服4 天冷了,穿棉襖8 """ lst=Son.mro() #檢視 super()物件呼叫順序 print(lst) """ [ <class '__main__.Son'>, <class '__main__.Man'>, <class '__main__.Woman'>, <class '__main__.Human'>, <class 'object'> ] """ # 3.相關函式 # 1.issubclass 判斷誰是否是誰子類 """ 在判斷子父關係時,只要在一條繼承鏈上,就有繼承關係 語法: 1.issubclass(子類,父類) 滿足返回True 2.issubclass(子類,(父類1,父類2,....)) 只要滿足一個就返回True """ res=issubclass(Son,Man) #True res=issubclass(Son,Human) #True print(res) # 2.isinstance 判斷物件是否是這個類(物件與類之間的關係) """ 在判斷物件型別時,只要在一條繼承鏈上,就有繼承關係 語法與issubclass一樣 """ class Car(): pass obj = Son() print(isinstance(obj,Man)) #True print(isinstance(obj,Human)) #True print(isinstance(obj,Car)) #False print(isinstance(obj,(Car,Human)))#True
2.多型
# 1.多型 """ 多型: 不同的子類物件,呼叫相同的父類方法,產生不同的執行結果 特徵: 繼承,重寫,針對於物件 作用: 在公司中,統一命名規則 """ class Soldier(): #士兵 def attack(self): #攻擊 pass def back(self): #撤退 pass class Army(Soldier): #陸軍 def attack(self): print("包子雷") def back(self): print("輕功水上漂") class Navy(Soldier): #海軍 def attack(self): print("魚叉") def back(self): print("水遁") class AirForce(Soldier): def attack(self): print("導彈") def back(self): print("跳傘,落地成盒") # 建立陸軍士兵 objArmy=Army() # 建立海軍士兵 objNavy=Navy() # 建立空軍士兵 objAirForce=AirForce() # 整裝待發 lst=[objArmy,objNavy,objAirForce] strvar=""" 1.全軍出擊 2.全體撤退 3.陸軍掩護其他兵種撤退 各就各位,將軍請下令: """ num=input(strvar) for i in lst: if num=="1": i.attack() elif num=="2": i.back() elif num=="3": if isinstance(i,Army): i.attack() else: i.back() else: print("聽不清~~") break