python学习19类5之多态与鸭子模型

''''''
'''
一、多态
1.Python中多态是指一类事物有多种形态。
'''

class Animal:
def run(self):
raise AttributeError('子类必须实现这个方法') #抛出异常


class People(Animal):
def run(self):
print('人正在走')

class Pig(Animal):
def run(self):
print('pig is walking')


class Dog(Animal):
def run(self):
print('dog is running')

peo1=People()
pig1=Pig()
d1=Dog()

peo1.run()
pig1.run()
d1.run()
'''
多态,可以这样理解,不同的对象都可以响应同一个方法,但执行结果各不相同
2.多态使用场景:(1)统一管理 (2)方法返回同一父类的不同子类对象 (3)方法参数接收同一父类的不同子类对象
3.多态实现:(1)不同子类继承同一父类,重写要执行的方法,保证执行结果各不相同
(2)采用鸭子模型的思想,为任意一个类植入需要的方法也可以实现
'''
#下面这个例子更加能让我们了解多态的本质

class Triangle:
def __init__(self, width, height):
self.width = width
self.height = height

def getArea(self):
area = self.width * self.height / 2
return area


class Square:
def __init__(self, size):
self.size = size

def getArea(self): # 同一个方法在不同的类中最终呈现出不同的效果,即为多态
area = self.size * self.size
return area


a = Triangle(5, 5)
print(a.getArea())
b = Square(5)
print(b.getArea())

'''
二、鸭子模型:只要一个东西看起来像鸭子,他就是鸭子
1.在鸭子模型中,关注的不是对象的类型本身,而是它是如何使用的。

例如,在不使用鸭子模型的语言中,我们可以编写一个函数,它接受一个类型为"鸭子"的对象,并调用它的"走"和"叫"方法。
在使用鸭子模型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的"走"和"叫"方法。
如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的"走"和"叫"方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
'''
class Duck():
def walk(self):
print('I walk like a duck')
def swim(self):
print('I swim like a duck')

class Person():
def walk(self):
print('this one walk like a duck')
def swim(self):
print('this man swim like a duck')
#可以很明显的看出,Person类拥有跟Duck类一样的方法,这时我们可以写一个函数,这个函数接受任何这种类似的类(有相同的方法的类),并且可以调用他们相同的方法
def fc(obj): #object类是Python中所有类的父类
obj.walk()
peo2=Person()
fc(peo2) #这时调用这个函数,就可以调用传入类的方法
'''

当有一个函数调用Duck类,并利用到了两个方法walk()和swim()。
我们传入Person类也一样可以运行,函数并不会检查对象的类型是不是Duck,只要他拥有walk()和swim()方法,就可以正确的被调用。
若传入的类没有要调用的方法,会报错,告诉你参数没有这个属性或方法
'''
'''
2.使用场景:(1)统一管理
(2)方法返回一个类似该类的对象
(3)方法接收一个类似该类的对象
'''