第十一章 (补充二)多态性
多态、多态性
多态
多态通俗理解起来,就像迪迦奥特曼有三种形态一样,怎么变还是迪迦奥特曼
- 定义:多态指的是一类事物有多种形态
示例如下:
'''动物有多种表现形态,人也是动物之一,在这里会说话就是动物'''
class Animal():
def speak(self):
print('动物发出的叫声--->', end='')
class Cat(Animal):
def speak(self):
print('喵喵喵')
class Dog(Animal):
def speak(self):
print('汪汪汪')
class People(Animal):
def speak(self):
print('啊啊啊')
ani = Animal()
ani.speak()
cat = Cat()
cat.speak()
ani.speak()
dog = Dog()
dog.speak()
ani.speak()
peo = People()
peo.speak()
# 结果
动物发出的叫声--->喵喵喵
动物发出的叫声--->汪汪汪
动物发出的叫声--->啊啊啊
多态性
- 多态性是指可以不用考虑对象具体类型的情况下直接使用对象,多态性是同一个操作,作用到不同实例而表现出不同实现方式的特性
拿上例来说:
# 多态性
# 统一接口,归一化操作
def Speack(animal):
animal.speak()
'''
因为所有的动物都会“说”,是同一操作,但是调用的参数不同,输出的结果不同,这就是多态性的体现
'''
Speack(cat)
Speack(dog)
Speack(peo)
# 结果
喵喵喵
汪汪汪
啊啊啊
多态性的优点:增加的程序的扩展性,使得每次来一个实例化的对象,都是以同一种形式去调用的,多态性还增加了程序的可扩展性,通过继承父类,减少了代码的冗余
class Pig(Animal):
def speak(self):
print('哼哼哼')
pig = Pig()
pig.speak()
鸭子类型
上述例子,只要是动物就可以直接使用相同的方法!多态的存在其实也限制了子类的使用方法(抽象类也是可以限制子类),定义子类的时候,必须有speak()方法,这样才能算的上动物类,所以python推荐使用“鸭子类型”,是一种不依赖于继承,也可以实现不考虑对象类型而使用对象。
class People():
def speak(self):
print('啊啊啊')
class Pig():
def speak(self):
print('哼哼哼')
class Dog():
def speak(self):
print('汪汪汪')
def Speak(animal):
animal.speak()
peo = People()
pig = Pig()
dog = Dog()
Speak(peo)
Speak(pig)
Speak(dog)
# 结果
啊啊啊
哼哼哼
汪汪汪
父类限制子类的行为
抽象类 (abc模块)
继承
主动报错示例:
'''父类限制子类'''
class Txt():
# 父类限制子类必须实现的功能
def read(self):
raise Exception("是文件就得有read功能")
class Conf(Txt):
pass
# 没有实现read功能,继承报错
class Bin(Txt):
def read(self):
print('读方法')
conf = Conf()
conf.read() # --->Exception: 是文件就得有read功能
bin = Bin()
bin.read()
组合
类和类之间代码冗余的问题可以通过继承来解决,或者super()方法等,其实我们还可以通过组合解决类与类之间代码冗余的问题
组合:一个类中以另外一个类的对象作为数据属性,就是类的组合,组合通常表示“有”的关系
class People():
def init(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Course():
def init(self, name, period, price):
self.name = name
self.period = period
self.price = price
class Student(Course, People):
def init(self, name, age, gender, course=None):
if course is None:
course = []
self.courses = course
super().__init__(name, age, gender)
实例化学生对象
stu = Student('HammerZe', 18, 'male')
实例化课程对象
python = Course('python','6m',10000)
linux = Course('linux','5m',10000)
组合
stu.courses.append(python.name)
stu.courses.append(linux.name)
print(stu.courses)
['python', 'linux']
面向对象的内置函数
init():初始化方法
str():打印对象的时候,自动触发的函数
del():在对象被删除的时候自动触发
call():对象加括号自动触发
enter():出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量
exit():with中代码块执行完毕时执行此方法
'''str() \ del() \ call()'''
class Foo():
def init(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
'''输出对象的时候打印,返回值只能是字符串'''
def __str__(self):
return '输出对象返回'
'''删除对象的时候打印'''
# 1.删除对象执行
# 2.如果不删除对象,程序执行完毕也自动执行__del__()
def __del__(self):
print('删除对象执行')
'''对象加括号自动触发'''
def __call__(self, *args, **kwargs):
print('对象加括号自动触发')
stu = Foo('HammerZe', 18, 'male')
print(stu) # --->输出对象返回
del stu.name # --->删除对象执行
stu() # --->对象加括号自动触发
'''enter(),exit() '''
class Open():
def init(self,name):
self.name = name
def __enter__(self):
print('出现with语句,触发此方法,如果该方法有返回值赋值给as后面的变量')
return 123
def __exit__(self, exc_type, exc_val, exc_tb):
print('with语句执行完毕触发此方法')
with Open('a.txt') as f:
pass
print(f) # --->123
--->出现with语句,触发此方法,如果该方法有返回值赋值给as后面的变量
--->with语句执行完毕触发此方法
反射
hasattr(obj,pro):按pro判断是否有无obj.pro属性
getattr(obj,pro,None):按pro判断是否有无obj.pro属性,没有返回None
setattr(obj,pro,value):设置obj.pro的值相当于obj.pro = value
delattr(obj,pro):删除obj.pro
class Info():
def init(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
oneself = Info('HammerZe', 18, 'male')
按字符串查找---hasattr
print(hasattr(oneself, 'name')) # --->True
print(hasattr(oneself, 'age')) # --->True
print(hasattr(oneself, 'gender')) # --->True
按字符串查找---getattr
print(getattr(oneself, 'name')) # --->HammerZe
print(getattr(oneself, 'age')) # --->18
print(getattr(oneself, 'gender')) # --->male
查找不存在的
print(getattr(oneself, 'weight', None)) # --->None
'''None只是默认值,可以修改'''
print(getattr(oneself, 'weight', 140)) # --->140
按字符串修改
setattr(oneself, 'name', 'li') # 相当于oneself.name = 'li'
print(oneself.name) # --->li
按字符串删除
delattr(oneself,'name') # 相当于del oneself.name
print(oneself.name) # --->AttributeError: 'Info' object has no attribute 'name'
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性