天天看點

多态的使用 | 手把手教你入門Python之六十七

上一篇: 對象相關的内置函數 | 手把手教你入門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正在睡覺           

不使用多态的問題

⾯向對象的三⼤特性:

  • 封裝:這是定義類的準則,根據對象的特點,将⾏為和屬性抽象出來,封裝到⼀個類中。
  • 繼承:這是設計類的技巧。⽗類與⼦類,主要展現在代碼的重⽤,不需要⼤量的編寫重複代碼。
  • 多态:不同的⼦類調⽤相同的⽗類⽅法,産⽣不同的執⾏結果,可以增加代碼的外部靈活度。多态是以繼承和重寫⽗類⽅法為前提的,它是⼀種調⽤⽅法的技巧,不會影響到類的内部設計。

多态是基于繼承,通過子類重寫父類的方法,達到不同的子類對象調用相同的父類方法,得到不同的結果。

作用是提高代碼的靈活度。

場景

  • 提供三個類:緝毒⽝、軍⽝、⼈
  • 緝毒⽝-->追查毒品,軍⽝-->攻擊假⼈,⼈-->讓⼩狗⼲活
  • 設計類來完成功能。
多态的使用 | 手把手教你入門Python之六十七

代碼實作:

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 的功能,其他⼩狗繼承它,這樣隻要是⼩狗類,則⾏為被統⼀起來了,我們⼈類完全可以保證,隻要是⼩狗的⼦類,找它⼲活肯定不會有問題。
  • 這樣⼈隻要⼀個⽅法就能逗任意種類的狗玩,哪怕是添加新的狗,⼈的類都不需要修改。
  • 圖示如下:
多态的使用 | 手把手教你入門Python之六十七
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 對象作為實參,就會産⽣不同的執⾏效果

多态總結

  • 定義:多态是⼀種使⽤對象的⽅式,⼦類重寫⽗類⽅法,調⽤不同⼦類對象的相同⽗類⽅法,可以産⽣不同的執⾏結果
  • 好處:調⽤靈活,有了多态,更容易編寫出通⽤的代碼,做出通⽤的程式設計,以适應需求的不斷變化!
  • 實作步驟:
    • 定義⽗類,并提供公共⽅法
    • 定義⼦類,并重寫⽗類⽅法
    • 傳遞⼦類對象給調⽤者,可以看到不同⼦類執⾏效果不同

配套視訊