本节内容接上一节,详看:
python面向对象-继承
概述
由于python是动态语言,所以多态的特性与JAVA这类静态语言有些区别
子类继承父类,就继承父类的方法,这是继承的特性
python中的多态:不同的 子类对象,调用 同一个父类方法,产生 不同 的结果
也就是说:多态依赖于继承特性
好处
- 增加了程序的灵活性
- 增加了程序的可扩展性
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()函数,可以判断对象是某个类型,还可以判断对象是某个类的子类