python学习笔记DAY18(面向对象编程-多态)
这是我个人的学习笔记,都赖于(egon老师)的分享,以下是老师博客的原地址:
https://www.cnblogs.com/xiaoyuanqujing/articles/11640888.html
面向对象编程(多态)
一、多态与多态性
- 多态:指的是一种事务有多种形态。(比如动物有多种形态的表现:猫、狗、猪)
class Animal: # 以下全部属于同一类型:动物
def talk(self):
print("会发出声音")
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()
- 多态性:指的是可以在不考虑对象具体类型的的情况下,直接使用对象。这需要在设计程序时,把对象的使用方法统一成一种:例如,cat\dog\pig 都是动物,只要是动物肯定有talk方法,于是我们可以不用考虑他们三者具体是什么类型的动物,而直接使用
cat.talk()、dog.talk()、pig.talk()
- 更进一步,我们可以定义一个统一的接口来使用
def talk(animal):
animal.talk()
talk(cat) 喵喵 \ talk(dog) 汪汪 \ talk(pig) 哼哼
- python中一切皆对象,本身就支持多态性,例如:
t = ("nida",)
s = "nida"
l = ["nida",78]
se = {"nida"}
d = {"name":"nida"}
print(type(t)) #<class 'tuple'>
print(type(s)) #<class 'str'>
print(type(l)) #<class 'list'>
print(type(se)) #<class 'set'>
print(type(d)) #<class 'dict'>
print(len(t)) # 1
print(len(s)) # 4
print(len(l)) # 2
print(len(se)) # 1
print(len(d)) # 1
如上代码:python内置了统一的接口,所以我们可以在不考虑对象类型,直接统计对象长度
- 多态性的好处在于增强了程序的灵活性和扩展性,比如继承Animal类创建了一个新的类,实例化得到对象obj,可以使用相同的方式使用obj.talk()
class Wolf(Animal):
def talk(self):
print("嗷..")
wolf = Wolf() # 实例化出狼的对象
wolf.talk() # 不管狼属于什么类型,我们知道它一定会有talk,直接调用即可
- 综上所述:多态性的本质在于,不同的类中定义有相同的方法名,这样我们就可以不考虑类,而用统一的方式去使用对象,可以通过在父类引入抽象类的概念来硬性限制子类必须有的某些方法名:
import abc
# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod # 该装饰器限制子类必须定义一个名为talk的方法
def talk(self): # 抽象方法中无需实现具体的功能
pass
class Cat(Animal): # 只要继承了Animal的子类都必须遵循Animal规定的标准
def talk(self):
print("喵喵")
cat = Cat() # 如果子类中没有按照要求制定talk方法,就会抛出:TypeError,无法实例化
重点:其实父类更多的不是用来实现功能的,基于继承实现这种多态的思想,父类更多的是用来规范和制定标准的。
二、鸭子类型
其实,我们完全可以不依赖继承,只需要制造出外观和行为相同的对象,同样可以实现不考虑对象类型而使用对象,这正是python崇尚的“鸭子类型”:“如果看起来像,叫声也像,走起路来也像鸭子,那么它就是鸭子。”比起继承的方式,鸭子类型在某种程度是哪个实现了程序的松耦合度:
# 以下两个类,看起来都像是文件,所以就可以当文件一样用,但是他们并无关系
class Txt: # txt 有两个与文件类型同名的方法,read,write
def rdad(self):
pass
def write(self):
pass
class Disk: # disk 也有两个与文件类型同名的方法,read,write
def rdad(self):
pass
def write(self):
pass

浙公网安备 33010602011771号