多态概述

多态没有语法,但是多态有表现形式!
Python 或其它编程语言中,对于多态的操作都没有提供固定的语法操作步骤,但是所有可能出现多态的业务中,都是一个入口(功能开始的地方是同一个地方),多个出口(根据参与解决问题的对象不同,得到的结果不同)

1:医院【治疗的行为】 --> 功能开始的地方

宠物猫去医院[治疗宠物猫]
宠物狗去医院[治疗宠物狗] --> 结果不同

多态的体现

class Pet:
    """定义一个宠物类""" 
    def __init__(self, name):
        self.name = name
    
    def cure(self):
        """治疗的方法"""
        print(f"{self.name}开始治疗了")

class Cat(Pet):
    """定义一个宠物猫类"""
    def cure(self):
        print("喵~")
        super().cure()

class Dog(Pet):
    """定义一个宠物狗类"""
    def cure(self):
        print("汪~")
        super().cure()


def hospital(Pet):
    Pet.cure()

cat = Cat("小花")
dog = Dog("小黑")

hospital(cat)
hospital(dog)

# 喵~
# 小花开始治疗了
# 汪~
# 小黑开始治疗了

多态的好处

多态的好处就是,当我们需要传入 CatDog 时,我们只需要接收 Pet 类型就可以了,因为 CatDog 都是 Pet 类型,然后,按照 Pet 类型进行操作即可。

由于 Pet 类型有 cure() 方法,因此,传入的任意类型,只要是 Pet 类或者子类,就会自动调用实际类型的 cure() 方法,这就是多态的意思!

对于一个变量,我们只需要知道它是 Pet 类型,无需确切地知道它的子类型,就可以放心地调用 cure() 方法,而具体的 cure() 方法是作用在 Cat 还是 Dog ,是由运行时该对象的确切类型决定,这就是多态的真正威力,调用方法只管调用,不管细节。而当我们新增一种 Pet 的子类时,只要确保 cure() 方法编写正确,不用管原来的代码是如何调用的。这就是著名的 开闭 原则!

对扩展开放: 允许新增 Pet 子类

对修改封闭:不需要修改依赖 Pet 类型的hospital函数

静态语言 vs 动态语言

对于静态语言(如 Java)来说,如果需要传入Pet 类型,则传入的对象必须是 Pet 类型或者它的子类,否则,将无法调用 cure() 方法。

对于 Python这样的动态语言来说,则不一定需要传入 Pet 类型,我们只需要保证传入的对象有一个 cure() 方法就可以了。

这就是动态语言的 鸭子类型。一个对象只要看起来像鸭子,走起路来像鸭子,那么它就可以被看做是鸭子。