Python | 多态

至今不是很理解,先把现有理解记录下,日后在编程过程中有了更深更正确的理解,再来更正。

本文记录在学习过程中听说了三种多态,下文使用的“第一种说法”等分类方法是为方便记录的、纯粹的个人分类。

目录:

一、我所见到的对多态的三种解释

二、鸭子模型

—————正文—————

一、我所见到的对多态的三种解释

1. 不同的子类对象,调用相同的父类方法,产生不同的执行结果

 目的:增加代码的灵活性

 以继承和重写父类方法为前提

 是调用方法的技巧,不会影响到类的内部设计

class Dog(object):
    def __init__(self, name):
        self.name = name

    def play(self):
        print("%s jump jump play" % self.name)


class XiaotianDog(Dog):
    def play(self):
        print("%s fly fly play" % self.name)


class Person(object):
    def __init__(self, name):
        self.name = name

    def play_with_dog(self, dog):
        print("%s and %s happy happy play" % (self.name, dog.name))
        dog.play()  # 不同的对象,调用相同的方法,产生不同的结果


wangcai = Dog("wangcai")
dawang = XiaotianDog("dawang")

xiaoming = Person("xiaoming")

# xiaoming.play_with_dog("wangcai")  错误啦
xiaoming.play_with_dog(wangcai)  # 要传进去的是狗对象
xiaoming.play_with_dog(dawang)


2. 一个对象具有多种形态,在不同的环境中以不同的形态展示其功能,称该对象具有多态特征
多态发生在【继承】关系的基础之上
 1 class Teacher():
 2     def teach(self):
 3         print("teach---")
 4 
 5 
 6 class Driver():
 7     def drive(self):
 8         print("drive---")
 9 
10 
11 class Man(Teacher, Driver):
12     def teach(self):
13         print("teach python")
14 
15     def drive(self):
16         print("drive car")
17 
18 
19 class Demo():
20     def travel(self, driver):
21         driver.drive()
22 
23     def study(self,teacher):
24         teacher.teach()
25 
26 
27 # 创建一个 司机对象,来完成旅行开车这件事
28 d = Driver()
29 demo1 = Demo()
30 demo1.travel(d)
31 
32 # 直接找到一个会开车的对象来完成开车这件事,不需要单独创建一个司机对象【多态的方法】
33 # 会开车的这个对象可能也会别的,不管,只要能开车就好了,说了这么多,上路不?哈哈哈哈
34 man = Man()
35 demo = Demo()
36 # man.drive()
37 demo.travel(man)
38 
39 # 按照多态的思路,如果有个地方需要一个teacher,也可以直接传这个man
40 demo.study(man)

3. 为不同的基础形态(数据类型)提供相关接口的能力
接口:指的是函数或方法

如print函数为字符串、整数、列表等等不同的数据类型都提供了接口,只需要用一个print就可以支持所有的数据类型,
而不需要定义并调用不同的函数,如:print_str、print_int、print_list等
1 print("hello")
2 print(23)
3 print([1, 2, 3])

假设要编写一个程序,创建猫、狗、羊三种动物,分别对应吃鱼、骨头、草,就可以定义Cat/Dog/Sheep三个类,并各自定义eat的方法。
Cat.eat()对应猫吃,Dog.eat()对应狗吃,Sheep.eat()对应羊吃,这样每个对象都有一个eat方法的接口,支持本动物吃东西。
即:为三个不同的对象提供了相同的接口。
如果不使用多态,则需要每个动物对应各自特有的cat_eat()/dog_eat()/sheep_eat。
 1 class Dog:
 2     def eat(self):
 3         print("我是狗,我吃骨头")
 4 
 5 
 6 class Cat:
 7     def eat(self):
 8         print("我是猫,我吃鱼")
 9 
10 
11 class Sheep:
12     def eat(self):
13         print("我是羊,我吃草")
14 
15 
16 def animal_eat(animal):
17     animal.eat()  #不同的动物(数据、对象)使用相同的接口
18 
19 
20 animal_eat(Dog())
21 animal_eat(Cat())
22 animal_eat(Sheep())
23 """
24 执行代码,打印:
25 我是狗,我吃骨头
26 我是猫,我吃鱼
27 我是羊,我吃草
28 """

二、鸭子模型

被调用的类没有使用继承,但是在语法层面满足了调用关系
特殊的多态表现形式

不仅是方法,属性也可以有鸭子类型,如,你需要一个name属性,那给一个带那么属性的就可以了

多态:在形式上和调用上都满足所谓的多态的要求
鸭子模型:在调用关系上满足,但是在形式上不满足
 1 # 要求:找一个人过来教某一样东西
 2 class Teacher():
 3     def teach(self):
 4         print("teach---")
 5 
 6 
 7 class Man(Teacher):
 8     # def teach(self):
 9     #     print("teach python")
10 
11     def drive(self):
12         print("drive car")
13 
14 
15 class Demo():
16     def study(self,teacher):
17         teacher.teach()
18 
19 
20 class TeachGame():
21     def teach(self):
22         print("教打游戏")
23 
24 
25 # 找继承了Teacher父类中teach方法的man,可以过来教某事
26 d = Demo()
27 man = Man()
28 d.study(man)
29 
30 # TeachGame这个类本身没有涉及继承,但是Dome的实例对象d,需要在study方法中执行的teach方法 正好在TeachGame中也存在
31 # 假当是多态的一个特殊形式
32 player = TeachGame()
33 d.study(player)

目前是傻傻分不清楚了。

【本文仅用于学习交流】

原文地址:https://www.cnblogs.com/ykit/p/11250378.html