上一篇: 對象相關的内置函數 | 手把手教你入門Python之六十六 下一篇: 檔案的打開與關閉 | 手把手教你入門Python之六十八 本文來自于千鋒教育在阿裡雲開發者社群學習中心上線課程 《Python入門2020最新大課》 ,主講人姜偉。
多态的使用
子類重寫父類方法
繼承的特點:如果一個類A繼承自類B,由類A建立出來的執行個體對象都能直接使用類B裡定義的方法。
1、子類的實作和父類的實作完全不一樣,子類可以選擇重寫父類的方法。
2、子類在父類的基礎上又有更多的實作
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def sleep(self):
print(self.name + '正在睡覺')
class Student(Person):
def __init__(self, name, age, school):
# self.name = name
# self.age = age
# 子類在父類實作的基礎上,又添加了自己新的功能
# 調用父類方法的兩種方式:
# 1. 父類名.方法名(self, 參數清單)
# Person.__init__(self, name, age)
# 2. 使用super直接調用父類的方法,推薦使用
super(Student, self).__init__(name, age)
self.school = school
def sleep(self):
print(self.name + '正在課間休息時睡覺')
def study(self):
print(self.name + '正在學習')
# s = Student('jerry', 20) # 調用了父類的 __init__ 方法
s = Student('jerry', 20, '春天花花幼稚園')
# s.sleep() # jerry正在睡覺 調用了父類的 sleep 方法
print(Student.__mro__) # method resolution order
s.sleep() # jerry正在課間休息時睡覺
p = Person('jack', 21)
p.sleep() # jack正在睡覺
不使用多态的問題
⾯向對象的三⼤特性:
- 封裝:這是定義類的準則,根據對象的特點,将⾏為和屬性抽象出來,封裝到⼀個類中。
- 繼承:這是設計類的技巧。⽗類與⼦類,主要展現在代碼的重⽤,不需要⼤量的編寫重複代碼。
- 多态:不同的⼦類調⽤相同的⽗類⽅法,産⽣不同的執⾏結果,可以增加代碼的外部靈活度。多态是以繼承和重寫⽗類⽅法為前提的,它是⼀種調⽤⽅法的技巧,不會影響到類的内部設計。
多态是基于繼承,通過子類重寫父類的方法,達到不同的子類對象調用相同的父類方法,得到不同的結果。
作用是提高代碼的靈活度。
場景
- 提供三個類:緝毒⽝、軍⽝、⼈
- 緝毒⽝-->追查毒品,軍⽝-->攻擊假⼈,⼈-->讓⼩狗⼲活
- 設計類來完成功能。

代碼實作:
class ArmyDog(object):
def bite_enemy(self):
print('追擊敵⼈')
class DrugDog(object):
def track_drug(self):
print('追查毒品')
class Person(object):
def work_with_army(self, dog):
dog.bite_enemy()
def work_with_drug(self, dog):
dog.track_drug()
ad = ArmyDog()
dd = DrugDog()
p = Person()
p.work_with_army(ad)
p.work_with_drug(dd)
思考:這段代碼設是否有問題?
新增需求:此時,⼜多了⼀個⽝種,就⼜需要在Person類⾥建立⼀個⽅法,讓這個⽅法操作新的狗。
class XiaoTianDog(object):
def eat_moon(self):
print('哮天⽝把⽉亮吃了')
class Person(object):
def work_with_xiaotian(self, dog): # 添加⽅法
dog.eat_moon()
Person 類總是不斷的添加新的功能,每次都需要改動Person類的源碼,程式的擴充性太差了!
- 最好是提供⼀個⽗類 Dog,具備 work 的功能,其他⼩狗繼承它,這樣隻要是⼩狗類,則⾏為被統⼀起來了,我們⼈類完全可以保證,隻要是⼩狗的⼦類,找它⼲活肯定不會有問題。
- 這樣⼈隻要⼀個⽅法就能逗任意種類的狗玩,哪怕是添加新的狗,⼈的類都不需要修改。
- 圖示如下:
class Dog(object):
def work(self): # ⽗類提供統⼀的⽅法,哪怕是空⽅法
pass
class ArmyDog(Dog): # 繼承 Dog
def work(self): # ⼦類重寫⽅法,并且處理⾃⼰的⾏為
print('追擊敵⼈')
class DrugDog(Dog):
def work(self):
print('追查毒品')
class Person(object):
def work_with_dog(self, dog):
dog.work() # 使⽤⼩狗可以根據對象的不同⽽産⽣不同的運⾏效果, 保障了代碼的穩定性
# ⼦類對象可以當作⽗類來使⽤
dog = Dog()
ad = ArmyDog()
dd = DrugDog()
p = Person()
p.work_with_dog(dog)
p.work_with_dog(ad) # 同⼀個⽅法,隻要是 Dog 的⼦類就可以傳遞,提供了代碼的靈活性
p.work_with_dog(dd) # 并且傳遞不同對象,最終 work_with_dog 産⽣了不同的執⾏效果
- 最終效果
- Person 類中隻需要調⽤ Dog 對象 work() ⽅法,⽽不關⼼具體是 什麼狗
- work() ⽅法是在 Dog ⽗類中定義的,⼦類重寫并處理不同⽅式的實作
- 在程式執⾏時,傳⼊不同的 Dog 對象作為實參,就會産⽣不同的執⾏效果
多态總結
- 定義:多态是⼀種使⽤對象的⽅式,⼦類重寫⽗類⽅法,調⽤不同⼦類對象的相同⽗類⽅法,可以産⽣不同的執⾏結果
- 好處:調⽤靈活,有了多态,更容易編寫出通⽤的代碼,做出通⽤的程式設計,以适應需求的不斷變化!
- 實作步驟:
- 定義⽗類,并提供公共⽅法
- 定義⼦類,并重寫⽗類⽅法
- 傳遞⼦類對象給調⽤者,可以看到不同⼦類執⾏效果不同