跳转至

OOP-多态

  • 多态在python中不是语法,是一种思想因为python本身就是一个多态语言(万物皆对象): 多个不同类的对象,都具有一些共同的特性,这些对象中的任何一个对象,都可以调用这些共同的特性,但是,因为是不同类的对象,所以,在调用同一个特性时,会表现出不同的行为
  • 同一个对象在不同情况下有不同的状态出现
  • 一种调用方式,可以有不同的调用结果
  • 多态能够提高代码的复用性,让代码更加精简易读,并且降低了代码的耦合度(紧密配合与相互影响的程度),提升了代码的扩展性

demo1

  • 常见的我们经常使用的count()方法就是多态特性
obj = '小宇棒,小宇帅,小宇好厉害!'  # 变量引用字符串对象
print(obj.count('小宇'))  # 显示输出结果为:3
obj = ('小宇', '樱井', '小宇', '明步')  # 变量引用元组对象
print(obj.count('小宇'))  # 显示输出结果为:2
  • 上方代码中,“obj”就是多态对象,它可以是不同的对象,我们不管"obj"是什么对象(字符串或元组或其它),我们只需要这个"obj"有count()这个attribute,如果有这个方法,那就能做处理.但是,虽然调用的方法都是同一个名称,因为处理的是不同的对象,实际上具体的处理行为是不一样的.

demo2

  • 这里找了一个很不错的例子,可以说明多态带来的特性以及优势
  • 比如一个动物园的饲养员,需要喂养老虎,狮子,以及狗熊

先做非多态处理

# 定义动物
class Lion:  # 定义狮子类
    def lion_eat(self):  # 定义进食函数
        print('狮子在吃东西!')

class Tiger:  # 定义老虎类
    def tiger_eat(self):  # 定义进食函数
        print('老虎在吃东西!')

class Bear:  # 定义狗熊类
    def bear_eat(self):  # 定义进食函数
        print('狗熊在吃东西!')
# 定义饲养员
class Feeder:
    def feed_lion(self, lion):  # 定义喂养狮子的函数
        lion.lion_eat()

    def feed_tiger(self, tiger): # 定义喂养老虎的函数
        tiger.tiger_eat()

    def feed_bear(self, bear): # 定义喂养猴子的函数
        bear.bear_eat()

# 喂养过程
feeder = Feeder()
lion = Lion()
feeder.feed_lion(lion)  # 显示输出结果为:狮子在吃东西!
tiger = Tiger()
feeder.feed_tiger(tiger)  # 显示输出结果为:老虎在吃东西!
bear = Bear()
feeder.feed_bear(bear)  # 显示输出结果为:狗熊在吃东西!

上方的代码虽然正常,但是如果动物园突然多了一只猴子需要喂养(/滑稽),那么就再增加一些代码

#定义动物
class Monkey:
    def monkey_eat(self):
        print('猴子在吃东西!')

#定义饲养员
class Feeder:
    ...
    def feed_monkey(self, monkey):
        monke.monkey_eat()
    ...

# 喂养过程
monkey = Monkey()
feeder.feed_monkey(monkey)

但是这样又凸显一个问题,如果动物源源不断的每天都增加,那么每天都要写很多代码(给饲养员增加代码,添加动物代码)来适应不同的动物进行喂食,

多态处理

class Lion:  # 定义狮子类
    def eat(self):  # 定义进食函数
        print('狮子在吃东西!')

class Tiger:  # 定义老虎类
    def eat(self):  # 定义进食函数
        print('老虎在吃东西!')

class Bear:  # 定义狗熊类
    def eat(self):  # 定义进食函数
        print('狗熊在吃东西!')

class Feeder:  # 定义饲养员类
    def feed_animal(self, animal):  # 定义喂食方法
        animal.eat()

# 喂养过程
feeder = Feeder()
animal = Lion()
feeder.feed_animal(animal)  # 显示输出结果为:我是狮子,在吃东西!
animal = Tiger()
feeder.feed_animal(animal)  # 显示输出结果为:我是狮子,在吃东西!
animal = Bear()
feeder.feed_animal(animal)  # 显示输出结果为:我是狗熊,在吃东西!
  • 在代码中规范了喂食的接口, 统一了喂食动作的命名,这样,多个类中都有一个相同的特性(eat方法)实例对象也就具有了这个相同的(eat方法)所以,不管调用的时候是哪一种实例对象(变量animal)都可以调用这个特性(eat方法),但是因为调用这个特性的实例对象(变量animal)不同,所以产生的行为(eat方法的处理过程)是不同的
  • 如果增加新的动物,那也只需要增加新的动物种类,以及喂养过程中对动物的实例化和调用喂养方法
#定义动物
class Monkey:
    def eat(self):
        print('猴子在吃东西!')
# 喂养过程
animal = Monkey()
feeder.feed_animal(animal)
  • 从这个示例我们也能够看出,喂食方法无需再重复定义,多喂养一种动物只需要定义一个新的类