多态
多态都是同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果
1 面向对象的三大特征之一
多态字面上理解多种形态:人(黑人,白人,黄种人)
2 发生多态的条件
1 继承,多态是发生在子类和父类之间的
2 重写,子类重写了父类的方法
下面举一个简单的例子说明一下
class A():
# 定义一个方法,打印自己的类名
def ziji(self,name):
print('%s...'%name)
class B(A):
def ziji(self,name):
print('%s...'%name)
class C(A):
def ziji(self,name):
print('%s...'%name)
a = A()
a.ziji('A')
# A...
a = B()
a.ziji('B')
# B...
a = C()
a.ziji('C')
# C...
这里说明一下,B,C 的类都继承A且都重写了父类的ziii()方法,
同一个变量a在执行同一个方法ziji()时,由于x指向的对象不同,所以实际调用的并不是同一个ziji()方法,这就是一种多态
其实在多态的基础上衍生了一种更灵活的编程机制
多态的实际应用
class Game1:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
class Game2:
def __init__(self,name):
self._name = name
# def __len__(self):
#
# return 5
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
# 定义一个函数
def speak(obj):
print('我要玩%s'%obj.name)
a = Game1('王者荣耀')
print(a.name)
speak(a) # 我要玩王者荣耀
speak(Game1) # 我要玩<property object at 0x0000018B6F835C78>
#
# a = Game2('吃鸡')
speak(a) # 我要玩吃鸡
实际上传入的参数对象只要有name属性的都可以调用speak()方法
例二:
def speak2(obj):
# 类型检查
if isinstance(obj,Game1):
print('我要玩%s'%obj.name)
a = Game1('LOL')
speak2(a) # 我要玩LOL
在speak2这个函数中做了一个类型检查,也就是只有obj是A类型的对象的时候,才可以正常使用,其他类型的对象无法使用该函数,这个函数其实就违反了多态
违反了多态的函数,只适用于一种类型的对象,无法处理其他类型的对象,这样导致函数的适用性非常差
下面再介绍一个鸭子模型,也是多态的一种
class Game():
def name(self,name):
name.play(self)
class Game1():
def play(self,name):
print('我要玩%s' % name)
a = Game()
a.name(Game1()) # 我要玩<__main__.Game object at 0x000001CD04D132E8>
实际上传入的参数对象只要有play()方法的都可以调用name方法
多态都是同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果
总结一下
面向对象的三大特征
封装 确保对象中的数据更安全
继承 保证了对象的可扩展性
多态 保证了程序的灵活性