欢迎来到赛兔子家园

什么是多态,Python多态及用法详解

在面向对象程序设计中,除了封装和继承特性外,多态也是一个非常重要的特性,本节就带领大家详细了解什么是多态。
我们都知道,Python 是弱类型语言,其最明显的特征是在使用变量时,无需为其指定具体的数据类型。这会导致一种情况,即同一变量可能会被先后赋值不同的类对象,例如:
class PLanguage:
    def say(self):
        print("赋值的是 PLanguage 类的实例对象")
class CPython:
    def say(self):
        print("赋值的是 CPython 类的实例对象")
a = PLanguage()
a.say()
a = CPython()
a.say()

运行结果:

赋值的是 PLanguage 类的实例对象
赋值的是 CPython 类的实例对象

可以看到,a 可以被先后赋值为 PLanguage 类和 CPython 类的对象,但这并不是多态。类的多态特性,还要满足以下 2 个前提条件:
1、继承:多态一定是发生在子类和父类之间
2、重写:子类重写了父类的方法。

对上面代码改写:

class PLanguage:
    def say(self):
        print("调用的是 Planguage 类的say方法")
class CPython(PLanguage):
    def say(self):
        print("调用的是 CPython 类的say方法")
class CLinux(PLanguage):
    def say(self):
        print("调用的是 CLinux 类的say方法")
a = PLanguage()
a.say()
a = CPython()
a.say()
a = CLinux()
a.say()

程序执行结果:

调用的是 Planguage 类的say方法
调用的是 CPython 类的say方法
调用的是 CLinux 类的say方法
可以看到,CPython 和 CLinux 都继承自 PLanguage 类,且各自都重写了父类的 say() 方法。从运行结果可以看出,同一变量 a 在执行同一个 say() 方法时,由于 a 实际表示不同的类实例对象,因此 a.say() 调用的并不是同一个类中的 say() 方法,这就是多态。
但是,仅仅学到这里,读者还无法领略 Python 类使用多态特性的精髓。其实,Python 在多态的基础上,衍生出了一种更灵活的编程机制。

继续对上面的程序进行改写:

class WhoSay:
    def say(self,who):
        who.say()
class PLanguage:
    def say(self):
        print("调用的是 Planguage 类的say方法")
class CPython(PLanguage):
    def say(self):
        print("调用的是 CPython 类的say方法")
class CLinux(PLanguage):
    def say(self):
        print("调用的是 CLinux 类的say方法")
a = WhoSay()
#调用 PLanguage 类的 say() 方法
a.say(PLanguage())
#调用 CPython 类的 say() 方法
a.say(CPython())
#调用 CLinux 类的 say() 方法
a.say(CLinux())

程序执行结果:

调用的是 Planguage 类的say方法
调用的是 CPython 类的say方法
调用的是 CLinux 类的say方法

此程序中,通过给 WhoSay 类中的 say() 函数添加一个 who 参数,其内部利用传入的 who 调用 say() 方法。这意味着,当调用 WhoSay 类中的 say() 方法时,我们传给 who 参数的是哪个类的实例对象,它就会调用那个类中的 say() 方法。

Python 这种由多态衍生出的更灵活的编程机制,又称为“鸭子模型”或“鸭子类型”。

 

posted on 2024-09-06 09:24  赛兔子  阅读(83)  评论(0)    收藏  举报

导航