WELCOME

不积跬步,无以至千里;不积小流,无以成江海。

Python面向对象--多态

多态

面向对象的三大特性:

封装:这是定义类的准则,根据对象的特点,将行为和属性抽象出来,封装到一个类中。

继承:这是设计类的技巧。父类与子类,主要体现在代码的重用,不需要大量的编写重复代码。

多态:不同的子类调用相同的父类方法,产生不同的执行结果,可以增加代码的外部灵活度。

多态是以继承和重写父类方法为前提的,它是一种调用方法的技巧,不会影响到类的内部设计。

 

场景
提供三个类:缉毒犬、军犬、人
缉毒犬-->追查毒品,军犬-->攻击假人,人-->让小狗干活
设计类来完成功能。

 

 1 class ArmyDog:
 2 
 3     def bite_enemy(self):
 4         print('追击敌人')
 5 
 6 
 7 class DrugDog:
 8 
 9     def track_drug(self):
10         print('追查毒品')
11 
12 
13 class Person:
14 
15     def work_with_army(self, dog):
16         dog.bite_enemy()
17 
18     def work_with_drug(self, dog):
19         dog.track_drug()
20 
21 
22 ad = ArmyDog()
23 dd = DrugDog()
24 
25 p = Person()
26 p.work_with_army(ad)
27 p.work_with_drug(dd)
思考:这段代码设是否有问题?

新增需求:此时,又多了一个犬种,就又需要在Person类里新建一个方法,让这个方法操作新的狗。

 

1 class XiaoTianDog(object):
2 
3     def eat_moon(self):
4         print('哮天犬把月亮吃了')
5 
6 class Person(object):
7 
8     def work_with_xiaotian(self, dog):  # 添加方法
9         dog.eat_moon()

 

  Person 类总是不断的添加新的功能,每次都需要改动Person类的源码,程序的扩展性太差了!

  最好是提供一个父类 Dog,具备 work 的功能,其他小狗继承它,这样只要是小狗类,则行为被统一起来了,我们人类完全可以保证,只要是小狗的子类,找它干活肯定不会有问题。
这样人只要一个方法就能逗任意种类的狗玩,哪怕是添加新的狗,人的类都不需要修改。
图示如下:

 

改进之后代码实现

 1 class Dog(object):
 2 
 3     def work(self):  # 父类提供统一的方法,哪怕是空方法
 4         pass
 5 
 6 
 7 class ArmyDog(Dog):  # 继承 Dog
 8 
 9     def work(self):  # 子类重写方法,并且处理自己的行为
10         print('追击敌人')
11 
12 
13 class DrugDog(Dog):
14 
15     def work(self):
16         print('追查毒品')
17 
18 
19 class XiaoTianDog(Dog):
20 
21     def work(self):
22         print('哮天犬把月亮吃了')
23 
24 
25 class Person(object):
26 
27     def work_with_dog(self, dog):
28         dog.work()  # 使用小狗可以根据对象的不同而产生不同的运行效果, 保障了代码的稳定性
29 
30 
31 # 子类对象可以当作父类来使用
32 dog = Dog()
33 ad = ArmyDog()
34 dd = DrugDog()
35 xt = XiaoTianDog()
36 
37 p = Person()
38 p.work_with_dog(dog)
39 p.work_with_dog(ad)  # 同一个方法,只要是 Dog 的子类就可以传递,提供了代码的灵活性
40 p.work_with_dog(dd)  # 并且传递不同对象,最终 work_with_dog 产生了不同的执行效果
41 p.work_with_dog(xt)
最终效果
  Person 类中只需要调用 Dog 对象 work() 方法,而不关心具体是 什么狗
  work() 方法是在 Dog 父类中定义的,子类重写并处理不同方式的实现
  在程序执行时,传入不同的 Dog 对象作为实参,就会产生不同的执行效果

 

多态总结

定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果
好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化!
实现步骤:
定义父类,并提供公共方法
定义子类,并重写父类方法
传递子类对象给调用者,可以看到不同子类执行效果不同

 

小练习

 1 class Person:
 2     def __init__(self, name):
 3         self.name = name
 4 
 5     def feed_pet(self, pet):  # pet即可以接收猫(cat),也可以接收dog,还可以接收tiger
 6         if isinstance(pet, Pet):
 7             # isinstance(obj,类):判断obj是不是类的对象,或者判断obj是不是该类子类的对象
 8             print('{}喜欢养宠物{},昵称为{}'.format(self.name, pet.role, pet.nickname))
 9         else:
10             print('不是宠物类型...')
11 
12 
13 class Pet:
14     role = 'Pet'
15 
16     def __init__(self, nickname, age):
17         self.nickname = nickname
18         self.age = age
19 
20     def show(self):
21         print('昵称:{},年龄:{}'.format(self.nickname, self.age))
22 
23 
24 class Cat(Pet):
25     role = ''
26 
27     def catch_mouse(self):
28         print('抓老鼠...')
29 
30 
31 class Dog(Pet):
32     role = ''
33 
34     def watch_house(self):
35         print('看家高手...')
36 
37 
38 class Tiger:
39     def eat(self):
40         print('太可怕了,可以吃人...')
41 
42 
43 # 创建对象
44 
45 cat = Cat('小花', 3)
46 
47 dog = Dog('大黄', 4)
48 
49 person = Person('tom')
50 
51 person.feed_pet(cat)
52 
53 tiger = Tiger()
54 
55 person = Person('jack')
56 
57 person.feed_pet(tiger)

 

posted @ 2022-04-01 19:06  Ambitious~  阅读(53)  评论(0)    收藏  举报