Loading

day 30 多态

1 多态和多态性

1.1 多态

同一事物有多种形态

多态指的是一类事物有多种形态,比如动物有多种形态:猫、狗、猪

class Animal:	 #同一类事物:动物
    def talk(self):
        pass
        
class Cat(Animal): 	#动物的形态之一:猫
    def talk(self):
        print('喵喵喵')
        
class Dog(Animal): 	#动物的形态之二:狗
    def talk(self):
        print('汪汪汪')
        
class Pig(Animal): 	#动物的形态之三:猪
    def talk(self):
        print('哼哼哼')

#实例化得到三个对象
>>> cat=Cat()
>>> dog=Dog()
>>> pig=Pig()

1.2 多态性

​ 多态性指的是可以在不用考虑对象具体类型的情况下而直接使用对象,这就需要在设计时,把对象的使用方法统一成一种:例如cat、dog、pig都是动物,但凡是动物肯定有talk方法,于是我们可以不用考虑它们三者的具体是什么类型的动物,而直接使用

点击查看代码
 class Animal: 		# 统一所有子类的方法
 	def say(self):
		 print('动物基本的发声频率。。。',end=' ')

 class People(Animal):
 	def say(self):
		 super().say()
		 print('嘤嘤嘤嘤嘤嘤嘤')

 class Dog(Animal):
	 def say(self):
		 super().say()
		 print('汪汪汪')

 class Pig(Animal):
 	def say(self):
 		super().say()
		 print('哼哼哼')

 obj1=People()
 obj2=Dog()
 obj3=Pig()

 obj1.say()
 obj2.say()
 obj3.say()

更进一步,我们可以定义一个统一的接口来使用

 定义统一的接口,接收传入的动物对象
def animal_say(animal):
 	animal.say()

 animal_say(obj1)
 animal_say(obj2)
 animal_say(obj3)

Python中一切皆对象,本身就支持多态性

# 我们可以在不考虑三者类型的情况下直接使用统计三个对象的长度
s.__len__()
l.__len__()
t.__len__()

# Python内置了一个统一的接口
len(s)
len(l)
len(t)

 print('hello'.__len__())
 print([1,2,3].__len__())
 print({'a':1,'b':2}.__len__())
-----------------------------------------------
 def my_len(val):
	 return val.__len__()

 print(my_len('hello'))
 print(my_len([1,2,3]))
 print(my_len({'a':1,'b':2}))

 len('hello')
 len([1,2,3])
 len({'a':1,'b':2})

​ 多态性的本质在于不同的类中定义有相同的方法名,这样我们就可以不考虑类而统一用一种方式去使用对象,可以通过在父类引入抽象类的概念来硬性限制子类必须有某些方法名

 import abc
 
 class Animal(metaclass=abc.ABCMeta): # 统一所有子类的标准
	 @abc.abstractmethod
 	 def say(self):
 		pass

 obj=Animal()	 # 不能实例化抽象类自己

 class People(Animal):
	 def say(self):
 		pass

 class Dog(Animal):
	 def say(self):
		 pass

 class Pig(Animal): 
 	 def say(self):
	 	pass

 obj1=People()	# 若子类中没有一个名为say的方法则会抛出异常TypeError,无法实例化
 obj2=Dog()
 obj3=Pig()

2 鸭子类型

​ 但其实我们完全可以不依赖于继承,只需要制造出外观和行为相同对象,同样可以实现不考虑对象类型而使用对象,这正是Python崇尚的“鸭子类型”(duck typing):“如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子”。比起继承的方式,鸭子类型在某种程度上实现了程序的松耦合度,如下

#二者看起来都像文件,因而就可以当文件一样去用,然而它们并没有直接的关系
class Txt: 	#Txt类有两个与文件类型同名的方法,即read和write
    def read(self):
        pass
    def write(self):
        pass

class Disk: 	#Disk类也有两个与文件类型同名的方法:read和write
    def read(self):
        pass
    def write(self):
        pass
点击查看代码
 class Cpu:
 	def read(self):
 		 print('cpu read')

 	def write(self):
		 print('cpu write')

 class Mem:
	 def read(self):
 		print('mem read')

	 def write(self):
 		print('mem write')

 class Txt:
 	def read(self):
		 print('txt read')

	 def write(self):
		 print('txt write')

 obj1=Cpu()
 obj2=Mem()
 obj3=Txt()



 obj1.read()
 obj1.write()

 obj2.read()
 obj2.write()
 
 obj3.read()
 obj3.write()
posted @ 2021-12-05 21:02  maju  阅读(38)  评论(0)    收藏  举报