多平台统一管理软件接口,如何实现多平台统一管理软件接口
249
2022-08-31
python面向对象(part4)--多态及设计原则(python的多态)
学习笔记 开发工具:Spyder
文章目录
多态
例子(判断哪些情况是多态)
重写内置可重写函数
举个例子1(`__str__`函数)举个例子2(`__repr__`函数)
运算符重载
算数运算符(对象在运算符左边)
例子(对象 + #)
反向算数运算符重载(对象在运算符右边)
例子(# + 对象)
复合运算符
例子(对象 += #)
比较运算符重载
例子
设计原则
设计原则类的单一职责依赖倒置组合复用原则里氏替换迪米特法则
多态
定义
父类的同一种动作或者行为,在不同的子类上有不同的实现。
作用
①继承将相关概念的共性进行抽象,多态则在共性的基础上,体现类型的个性化(一个行为有不同的实现)。 ②增强程序扩展性,体现开闭原则。
备注:开闭原则为对扩展开放,对修改关闭。
例子(判断哪些情况是多态)
类代码:
class Weapon: """ 武器 """ def __init__(self,atk): self.atk = atk def buy(self): print("购买武器") def attack(self): # 子类如果没有当前方法,就会报错 raise NotImplementedError()class Gun(Weapon): """ 枪 """ def __init__(self,atk,speed): super().__init__(atk) self.att_speed = speed def attack(self): print("开枪")class Grenade(Weapon): """ 手雷 """ def __init__(self, atk, range): super().__init__(atk) self.explode_range = range def attack(self): print("爆炸")
问:下面这两段代码,体现了多态么?
g01 = Gun(10, 1)g01.buy()g01.attack()
gren01 = Grenade(30, 5)gren01.buy()gren01.attack()
答:都没有,多态要求调用父类,执行子类,以上两段代码都是调用子类,所以均不是多态。
那什么时候才是多态呢?看下面一段代码:
g01 = Gun(10, 1)def my_use(weapon): weapon.attack() #调用父类my_use(g01) #执行子类
在这里,我们定义了一个my_use()方法。 在my_use()方法中,我们想要用父类的实例对象weapon来调用attack()方法,但实际上传入的参数为子类实例对象g01,所以在执行时,执行的是子类的attack()方法。这时,就满足了多态的要求,即调用父类,执行子类。这里的调用父类,即我们认为的观念上的父类,但实际传入的实例对象为子类的实例对象。
PS:个人理解,若有错误,请求指出。
重写
子类实现了父类中相同的方法(方法名、参数),在调用该方法时,实际调用的是子类的方法。
内置可重写函数
在python中,以双下划线开头,并以双下划线结尾的是,系统定义的成员。我们可以在自定义类中进行重写,进而改变其行为。 比如:__str__函数:将对象转换为字符串(对人友好的)__repr__函数:将对象转换为字符串(解释器可识别的)
举个例子1(__str__函数)
代码:
class BunnyA: def __init__(self, name, age): self.name = name self.age = ageclass BunnyB: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return "我叫%s,我是一只%d个月大的兔兔" % (self.name, self.age)b0A = BunnyA("大白", 8)print(b0A)b0B = BunnyB("小黄", 7)print(b0B)
举个例子2(__repr__函数)
代码:
class BunnyA: def __init__(self, name, age): self.name = name self.age = ageclass BunnyB: def __init__(self, name, age): self.name = name self.age = age def __str__(self): #返回给人看 return "我叫%s,我是一只%d个月大的兔兔" % (self.name, self.age) def __repr__(self): #返回给解释器看 return "BunnyB('%s', %d)" % (self.name, self.age)b0A = BunnyA("大白", 8)print(b0A)print(b0A.__repr__())print("-----------------")b0B = BunnyB("小黄", 7)print(b0B)print(b0B.__repr__())print("-----------------")b0B2 = eval(b0B.__repr__())print(b0B2)
备注:eval()函数,可以在其中放入字符串(python代码的字符串),然后执行。
举个例子
运算符重载
运算符重载可以让自定义的类生成的对象(实例)能使用运算符进行操作。
算数运算符(对象在运算符左边)
例子(对象 + #)
代码:
class Vector: def __init__(self, x): self.x = x def __str__(self): return "向量的x变量是:%s"%self.x # 对象 + def __add__(self, other): return Vector(self.x + other)v01 = Vector(10)v02 = v01 + 5print(v02)
结果:
反向算数运算符重载(对象在运算符右边)
例子(# + 对象)
代码:
class Vector: def __init__(self, x): self.x = x def __str__(self): return "向量的x变量是:%s"%self.x # 对象 + def __add__(self, other): return Vector(self.x + other) # + 对象 def __radd__(self, other): return Vector(self.x + other)v01 = Vector(10)v02 = 1 + v01print(v02)
复合运算符
运用反向算数运算符来实现【+=】会创造新的对象,若我们不希望创建新的对象,且在原有对象上实现【+=】,则可以用复合运算符
例子(对象 += #)
代码:
class Vector: def __init__(self, x): self.x = x def __str__(self): return "向量的x变量是:%s"%self.x # 对象 + def __add__(self, other): return Vector(self.x + other) # + 对象 def __radd__(self, other): return Vector(self.x + other) # 累加:在原有对象基础上进行操作,不创建新对象. def __iadd__(self, other): self.x += other return selfv01 = Vector(10)print(id(v01))v01 += 1print(v01)print(id(v01))
比较运算符重载
例子
代码:
class Vector: def __init__(self, x): self.x = x def __str__(self): return "向量的x变量是:%s"%self.x # 对象 + def __add__(self, other): return Vector(self.x + other) # + 对象 def __radd__(self, other): return Vector(self.x + other) def __lt__(self, other): return self.x < otherv01 = Vector(10)print(v01 < 5)
结果:
设计原则
设计原则
对扩展开放,对修改关闭。 增加新功能,不改变原有代码。
类的单一职责
一个类有且只有一个改变它的原因。
依赖倒置
客户端代码(调用的类)尽量依赖(使用)抽象的组件。 抽象的是稳定的。实现是多变的。
组合复用原则
如果仅仅为了代码复用优先选择组合复用,而非继承复用。 组合的耦合性相对继承低。
里氏替换
父类出现的地方可以被子类替换,在替换后依然保持原功能。 子类要拥有父类的所有功能。 子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。
迪米特法则
类与类交互时,在满足功能要求的基础上,传递的数据量越少越好。因为这样可能降低耦合度。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~