python面向对象-多态

本节内容接上一节,详看:
python面向对象-继承

概述

由于python是动态语言,所以多态的特性与JAVA这类静态语言有些区别

子类继承父类,就继承父类的方法,这是继承的特性

python中的多态:不同的 子类对象,调用 同一个父类方法,产生 不同 的结果

也就是说:多态依赖于继承特性

好处

  1. 增加了程序的灵活性
  2. 增加了程序的可扩展性

python与C++/JAVA多态的区别

学过C++、JAVA的小伙伴,可以看本节,了解与python多态的区别

在静态语言中

(C++/JAVA/C#),定义变量必须声明变量的类型,代码如下:

/*
变量wang是Wangjianlin类型,也可以指向子类Wangsicong()的对象
*/
Wangjianlin wang=new Wangsicong()

在python中

在python这类动态语言中,变量的类型可以动态改变,所以这个特性无法直观的看到,代码如下:

#变量wang是不需要指定类型的,也可以动态改变,所以这个特性无法直观的看到
wang=Wangsicong()

多态 与 函数

在Wangjianlin类中增加go_home()方法

class Wangjianlin:
    def go_home():
        print("夫人,我回家了!")

然后定义函数call_wang_home()(不是类的方法),该函数调用上面go_home()方法,是王夫人喊Wangjianlin或Wangsicong回家,代码如下:

#注意是函数,而不是某个类的方法
def call_wang_home(wang):
    print("王夫人喊老王家人回家")
    wang.go_home()

测试调用:

call_wang_home(Wangjianlin())
call_wang_home(Wangsicong())

结果显示:

王夫人喊老王家人回家
夫人,我回家了!
夫人,我回家了!
总结:

子类Wangsicong虽然没有定义go_home()方法,但继承了父类的方法,所以可以正确调用

问题1:

Wangsicong类的应该打印“妈,我回家了!”,

解决问题:

子类覆盖父类的go_home()方法,代码如下:

def go_home():
    print("母亲,我回家了")

测试调用:

call_wang_homej(Wangjianlin())
call_wang_homej(Wangsicong())

结果显示:

王夫人喊老王家人回家
夫人,我回家了!
母亲,我回家了!

问题2:

由于python是动态语言,定义变量不需要类型,所以在定义形参时无法限制传入变量的类型

如果其他类也实现了go_home()方法,虽然没有继承Wangjianlin类,该类的对象也可以传入call_wang_home()函数,也能正常运行

代码如下:

#定义马云类
class Mayun:
    #实现go_home()方法
    def go_home():
        print("四海为家")

测试调用

call_wang_homej(Mayun())

执行结果如下:

王夫人喊老王家人回家
四海为家

虽然运行不报错,但是 不合理

解决问题:

在call_wang_homej()函数中,要判断传入的对象,只有是Wangjianlin类及其子类才可以继续运行,否则提示不许进门

通过isinstance(object, classinfo)函数实现,详细参见:
https://www.runoob.com/python/python-func-isinstance.html

代码如下:

def call_wang_home(wang):
    print("王夫人喊老王家人回家")
    if isinstance(wang,Wangjianiln):
        print("王夫人喊老王家人回家")
        wang.go_home()
    else:
        print("你不是老王家人,不许进门")

测试调用:

call_wang_homej(Wangjianlin())
call_wang_homej(Wangsicong())
call_wang_homej(Mayun())

显示结果:

王夫人喊老王家人回家
夫人,我回家了!
母亲,我回家了!
你不是老王家人,不许进门

总结:

isinstance()函数,可以判断对象是某个类型,还可以判断对象是某个类的子类


原文出处:/show_1EF2E2D9w7oL.html