目录
一、多态的引入
1、先看一个问题
2、使用传统的方法类解决
class Food:
name=None
def __init__(self,name):
self.name=name
class Fish(Food):
pass
class Bone(Food):
pass
class Animal:
name=None
def __init__(self,name):
self.name=name
class Cat(Animal):
pass
class Dog(Animal):
pass
class Master:
name=None
def __init__(self,name):
self.name=name
# 给猫猫喂鱼
def feed_cat(self,cat:Cat,fish:Fish):
print(f"主人:{self.name} 给动物:{cat.name} 喂的食物是:{fish.name}")
# 给小狗喂骨头
def feed_dog(self,dog:Dog,bone:Bone):
print(f"主人:{self.name} 给动物:{dog.name} 喂的食物是:{bone.name}")
# 测试
master=Master("小明")
cat=Cat("小花猫")
fish=Fish("黄花鱼")
dog=Dog("大黄狗")
bone=Bone("大棒骨")
master.feed_cat(cat,fish)
master.feed_dog(dog,bone)
问题分析:如果动物/食物的种类很多,怎么办?
传统的方法带来的问题是什么?如何解决?
1)问题是:代码的复用性不高,而且不利于代码维护和功能扩展
2)解决方案:引出->多态
二、多态介绍&特别说明
1、怎么理解多态
1)多态顾名思义即多种状态,不同的对象调用相同的方法,表现出不同的状态,称为多态
2)多态通常作用在继承关系上
说明:一个父类,具有多个子类,不同的子类对象调用相同的方法,执行的时候产生不同的状态,就是多态
2、实例演示
class Animal:
def cry(self):
pass
class Cat(Animal):
def cry(self):
print("小猫喵喵叫...")
class Dog(Animal):
def cry(self):
print("小狗汪汪叫...")
class Bird(Animal):
def cry(self):
print("小鸟渣渣叫...")
class Pig(Animal):
def cry(self):
print("小猪噜噜叫...")
# 注意:在Python面向对象编程中,子类对象可以传递给父类类型
def func(animal:Animal):
print(f"animal类型是{type(animal)}")
animal.cry()
# 创建对象
cat=Cat()
dog=Dog()
bird=Bird()
pig=Pig()
# 调用函数
func(cat)
func(dog)
func(bird)
func(pig)
3、多态的好处
1)增加了程序的灵活性,以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal),代码说明
2)增加了程序的可扩展性,通过继承Animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用
4、特别说明Python的多态特点
1)Python中函数/方法的参数是没有类型限制的,所以多态在Python中的体现并不是很严谨(比如:和java等强类型语言相比)
2)Python并不要求严格的继承体系,关注的不是对象的类型本身,而是它是否具有要调用的方法(行为)
举例说明:
class AA:
def hi(self):
print("AA-hi()...")
class BB:
def hi(self):
print("BB-hi()...")
def test(obj):
obj.hi()
aa=AA()
bb=BB()
test(aa)
test(bb)
三、主人喂食问题
使用多态的机制来解决主人喂食物的问题
# 使用多态特性优化程序
class Food:
name=None
def __init__(self,name):
self.name=name
class Fish(Food):
pass
class Bone(Food):
pass
class Animal:
name=None
def __init__(self,name):
self.name=name
class Cat(Animal):
pass
class Dog(Animal):
pass
class Master:
name=None
def __init__(self,name):
self.name=name
# # 给猫猫喂鱼
# def feed_cat(self,cat:Cat,fish:Fish):
# print(f"主人:{self.name} 给动物:{cat.name} 喂的食物是:{fish.name}")
#
# # 给小狗喂骨头
# def feed_dog(self,dog:Dog,bone:Bone):
# print(f"主人:{self.name} 给动物:{dog.name} 喂的食物是:{bone.name}")
# 主人给动物喂食物
def feed(self,aniaml:Animal,food:Food):
print(f"主人:{self.name} 给动物:{aniaml.name} 喂的食物是:{food.name}")
# 测试
master=Master("小明")
cat=Cat("小花猫")
fish=Fish("黄花鱼")
dog=Dog("大黄狗")
bone=Bone("大棒骨")
master.feed(cat,fish)
master.feed(dog,bone)
四、isinstance()函数
1、基本说明
1)isinstance()用于判断对象是否为某个类或其子类的对象
2)基本语法:isinstance(object,classinfo)
object:对象
classinfo:可以是类名、基本类型或者由它们组成的元组
2、实例演示
# isinstance使用案例
class AA:
pass
class BB(AA):
pass
class CC:
pass
# 创建对象
obj=BB()
# 分析输出的结果
print(f"obj是不是BB的对象:{isinstance(obj,BB)}")
print(f"obj是不是AA的对象:{isinstance(obj,AA)}")
print(f"obj是不是CC的对象:{isinstance(obj,CC)}")
print("------------------------")
num=9 # int类型
print(f"num是不是int:{isinstance(num,int)}")
print(f"num是不是str:{isinstance(num,str)}")
print(f"num是不是str/int/list:{isinstance(num,(str,int,list))}")