Python - 面向對象編程 - 三大特性之多態


前置知識

封裝

 

繼承

 

多態

  • 不同的子類對象調用相同的父類方法,產生不同的執行結果
  • 以繼承和重寫父類方法為前提
  • 是調用方法的技巧,不會影響到類的內部設計

程序猿和設計師都是人類,他們都重寫了父類的 work 方法,但他們都有自己的實現邏輯

  

多態的栗子一

需求

  • 定義 Dog 類封裝方法 game,普通狗狗簡單玩耍
  • 定義 ChaiQuan 繼承 Dog,重寫 game 方法,柴犬瘋瘋癲癲的玩耍
  • 定義 Person 類,封裝一個和狗玩的方法,在方法內部,直接調用狗對象調用玩耍的方法

 

類圖

 

實際代碼

class Dog:
    def __init__(self, name):
        self.name = name

    def game(self):
        print(f"{self.name} 狗狗在玩耍")


class ChaiQuan(Dog):
    def game(self):
        print(f"{self.name} 柴犬在瘋瘋癲癲的玩耍")


class Person:
    def __init__(self, name):
        self.name = name

    def gameWithDog(self, dog):
        print(f"{self.name} 正在和 {dog.name} 愉快的玩耍")
        # 直接通過狗實例對象調用 game 實例方法,不需要關心是哪種狗
        dog.game()


chai = ChaiQuan("小柴犬")
dog = Dog("旺財")
p = Person("小菠蘿")
p.gameWithDog(chai)
p.gameWithDog(dog)


# 輸出結果

小菠蘿 正在和 小柴犬 愉快的玩耍
小柴犬 柴犬在瘋瘋癲癲的玩耍

小菠蘿 正在和 旺財 愉快的玩耍
旺財 狗狗在玩耍 
  • Person 類中只需要讓狗對象調用 game 方法,而不用關心具體是什么狗
  • game 方法是在 Dog 父類中定義的
  • 在程序執行時,傳入不同的狗對象參數,gameWithDog 就會產生不同的執行結果

 

通過統一函數接口實現多態

class Dog(object):
    def sound(self):
        print("汪汪汪.....")


class Cat(object):
    def sound(self):
        print("喵喵喵.....")


def make_sound(animal):
    # 統一調用接口
    # 不管你傳進來是什么動物,我都調用sound()方法
    animal.sound()


dogObj = Dog()
catObj = Cat()
make_sound(dogObj)
make_sound(catObj)


# 輸出結果
汪汪汪.....
喵喵喵.....

  

通過抽象類實現多態

需求

  • 定義一個 Person 類,可以開車,也可以停車
  • 定義一個 Car 類,提供 drive、stop 的方法
  • 定義一個 Truck、BaoMa 類,繼承 Car 類,重寫 drive、stop 方法

 

類圖

 

實際代碼

class Car:
    def __init__(self, name):
        self.name = name

    def drive(self):
        # 拋出異常是防止通過 Car 直接定義實例對象
        # 如果 Car 的實例對象調用此方法會報錯,必須由子類重寫才正確
        raise NotImplementedError("Subclass must implement abstract method")

    def stop(self):
        raise NotImplementedError("Subclass must implement abstract method")


class Truck(Car):
    def drive(self):
        print(f"{self.name} Truck 准備上路了")

    def stop(self):
        print(f"{self.name} Truck 准備停車")


class BaoMa(Car):
    def drive(self):
        print(f"{self.name} BaoMa 要跑到100km/h了")

    def stop(self):
        print(f"{self.name} BaoMa 漂移停車")


class Person:
    def __init__(self, name):
        self.name = name

    def driveCar(self, car):
        print(f"{self.name} 准備開車上路了")
        car.drive()

    def stopCar(self, car):
        print(f"{self.name} 准備靠邊停車")
        car.stop()


person = Person("小菠蘿")
truck = Truck("小卡車")
baoma = BaoMa("大寶馬")
person.driveCar(truck)
person.stopCar(baoma)


# 輸出結果
小菠蘿 准備開車上路了
小卡車 Truck 准備上路了

小菠蘿 准備靠邊停車
大寶馬 BaoMa 漂移停車

Car 是一個抽象類,並不需要通過它創建實例對象,所以 Car 的實例方法都會拋出異常,由子類繼承 Car,然后重寫方法才能正常調用

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM