【python面向对象】继承与多态(二)
文章目录
- 内置可重写函数
- __str__函数
- __repr__函数
- 练习
- 运算符重载
- 定义
- 多继承
- 面向对象设计思想补充
- 里氏替换(继承后的重写)
- 迪米特法则(类与类交互的原则)
- 总结
内置可重写函数
Python中,以双下划线开头、双下划线结尾的是系统定义的成员。我们可以在自定义的类中进行重写,从而
类中进行重写,从而改变其行为。
__str__函数
__str__函数:将对象转换为字符串(对人友好的)。
class StudentModel:"""学生模型"""def __init__(self,name="",age=0,score=0,id=0):self.name = nameself.age = ageself.score = scoreself.id = id# 对象-->字符串(随意格式)def __str__(self):return "我叫%s,编号是%d ,年龄是%d ,成绩是:%d"%(self.name,self.id,self.age,self.score)s01 = StudentModel("无忌",27,100,101)
str01 = str(s01)
print(str01)#我叫无忌,编号是101 ,年龄是27 ,成绩是:100
print(s01)#我叫无忌,编号是101 ,年龄是27 ,成绩是:100
__repr__函数
__repr__函数:将对象转换为字符串(解释器可识别的)。
"""内置可重写函数
"""
class StudentModel:"""学生模型"""def __init__(self,name="",age=0,score=0,id=0):self.name = nameself.age = ageself.score = scoreself.id = id# 对象-->字符串(随意格式)def __str__(self):return "我叫%s,编号是%d ,年龄是%d ,成绩是:%d"%(self.name,self.id,self.age,self.score)# 对象-->字符串(解释器可识别,有格式)def __repr__(self):return "StudentModel('%s',%d,%d,%d)" % (self.name,self.age, self.score,self.id)s01 = StudentModel("无忌",27,100,101)
str01 = str(s01)
print(str01)#我叫无忌,编号是101 ,年龄是27 ,成绩是:100
print(s01)#我叫无忌,编号是101 ,年龄是27 ,成绩是:100str02 = repr(s01)
print(str02)#根据字符串执行python代码
re = eval("1+2*5")
print(re)#11#克隆对象
#repr返回python格式的字符串
#eval根据字符串执行代码
s02 = eval(repr(s01))
print(s02.name)#无忌
s02.name = "老张"
print(s01.name)#无忌
print(s02.name)#老张
练习
创建Enemy类对象,将对象打印在控制台中(格式自定义)。
克隆Enemy类对象,体会克隆对象变量的改变不影响原对象。
class Enemy:def __init__(self,name,attack,hp,defense):self.name = nameself.attack =attackself.hp = hpself.defense = defensedef __str__(self):return "敌人的名字:%s,敌人的攻击力:%d,敌人的生命值:%d,敌人的防御值:%d"%(self.name,self.attack,self.hp,self.defense)def __repr__(self):return "Enemy('%s',%d,%d,%d)" % (self.name, self.attack, self.hp, self.defense)e01 = Enemy("张三",100,200,100)
print(str(e01))r01 = Enemy("李四",100,200,100)
e02 = eval(repr(r01))
print(e02.name)
运算符重载
定义
让自定义的类生成的对象(实例)能够使用运算符进行操作。
"""运算符重载
"""
class Vector1:def __init__(self,x):self.x = xdef __str__(self):return "一维向量的分量是:"+str(self.x)def __add__(self,other):return Vector1(self.x + other)def __radd__(self,other):return Vector1(self.x + other)def __iadd__(self,other):self.x += otherreturn selfv01 = Vector1(10)
print(v01 + 2)#v01.__add__(2)#一维向量的分量是:12print (2+ v01)#v01.__radd__(2)#一维向量的分量是:12print(id(v01))#1842544712336
#重写__iadd__,实现在原对象基础上的变化。
#如果重写__iadd__,默认使用__add__,一般会产生新对象。
v01 += 2
print(v01,id(v01))#一维向量的分量是:12 1842544712336list01 =[1]
print(id (list01))#2062509301504
#生成新对象
re = list01 +[2]
print(re, id(re))#[1, 2] 2062510616320
#在原有对象基础上,累加.
list01 += [2]
print(list01 , id (list01))#[1, 2] 2062509301504
多继承
- 父类(基类、超类)、子类(派生类)。
- 父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。
- 单继承:类只有一个(例如Java,C#)。
- 多继承:父类有多个(例如C++,Python)。
- Object类:任何类都直接或间接继承自object类。
- 多继承语法:
类自身–>父类继承列表(由左至右)–>再上层父类
D–>B–>C–>A
"""多继承 -- 语法MRO:同名方法的解析顺序
"""
class A:def m01(self):print("A - m01")class B(A):def m01(self):print("B - m01")class C(A):def m01(self):print("C - m01")class D(B,C):def m02(self):self.m01()d01 = D()
d01.m02()
#B - m01
#mro():同名方法的解析顺序
print(D.mro())
#[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
面向对象设计思想补充
里氏替换(继承后的重写)
Liskov Substitution Principle
父类出现的地方可以被子类替换,在替换后依然保持原功能。
子类要拥有父类的所有功能。
子类在重写父类方法时,尽量选择扩展重写,防止改变了功能。
迪米特法则(类与类交互的原则)
Law of Demeter
不要和陌生人说话。
类与类交互时,在满足功能要求的基础上,传递的数据量越少越好。因为这样可能降低耦合度。
总结
面向对象:考虑问题从对象的角度出发,让程序变得灵活。
抽象:从多个事物中,舍弃个别的/非本质的特征(不重要),抽出共性(重要的)的本质过程。
三大特征∶
- 封装:将每个变化点单独分解到不同的类中。
例如:老张开车去东北
做法:定义人类,定义车类。
- 继承:重用现有类的功能和概念,并在此基础上进行扩展。(统一概念,代码复用)
例如:图形管理器,统计圆形/矩形....面积。
做法:用图形类代表/约束,圆形/矩形..具有计算面积的方法。
- 多态:调用父"抽象的"方法,执行子类"具体的"方法。
重写:覆盖父类那个比较抽象的方法。
例如:图形管理器调用图形的计算面积方法,具体图形必须重写图形的计算面积方法。
继承是共性(计算面积),多态是个性(长 * 宽 / pi * i ** 2)。
设计原则:
- 开闭原则:允许增加新功能﹐不允许修改客户端代码。
- 单一职责:一个有且只有一个改变的原因。
- 依赖倒置:调用抽象(父),不要调用具体(子)
抽象不要依赖具体。 - 组合复用:如果仅仅是代码的复用,优先使用组合。
- 里氏替换
- 迪米特法则
类与类关系
泛化(继承):泛化(从具体到抽象)、继承(从抽象到具体)
组合:关联(做成成员变量)
组合:依赖(做成方法参数)
【python面向对象】继承与多态(二)相关推荐
- python中的继承有什么特点_Python中 什么是面向对象-继承和多态
文字有点长,对于不想看文字的朋友,可以去这里看视频,内容和这个文字一样的,视频可能更好理解 https://www.piqizhu.com/v/zaX9K4pd4GE 上一篇文章<python教 ...
- Python之路-面向对象继承和多态类属性和实例属性类方法和静态方法
一.面向对象 编程方式 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发"更快更好更强-& ...
- python中继承和多态
继承和多态 继承 引入继承 我们有这样一个需求 模仿英雄联盟定义两个英雄类1.英雄要有昵称.攻击力.生命值属性2.实例化出两个英雄对象3.英雄之间可以互殴,被殴打的一方掉血,血量小于0则判断为死亡 那 ...
- python的继承和多态
什么是继承? 在生活中,大家都应该听过这个词,比如儿子继承他老子的财产,那么在python中也有继承,但是有不少人比较难理解继承这个东西. 在python,所有的类都默认继承object类,因此obj ...
- 继承和多态二:虚析构函数
虽然我们已经知道了什么是继承和多态,也明白了多态依赖于继承,但是在多态中存在哪些问题呢? 多态中可能存在的内存泄露问题 例如下面的程序中,在圆形Circle的类中定义一个圆心的坐标,并且坐标是在堆中申 ...
- python完全支持面向对象编程思想_面向对象的编程思想和Python的继承和多态,特殊方法,引用计数...
面向对象的编程思想和Python的类,访问和属性,继承 在上一文中我们了解到了,私有的属性的访问方式:实例名._类名__私有属性名. 一.私有的属性如何对外提供公有的取值和赋值方法呢?提供公有的方法作 ...
- java多态简单例子6_Java_6、面向对象——继承和多态
继承 •继承是面向对象编程的三大特征之一,是一种基于已有类来创建新类的机制.由继承而得到的类称为子类(或派生类),被继承的类称为父类(或超类). •Java中每个类只允许有一个父类.语法如下:clas ...
- python面向对象继承_Python 面向对象 --- 继承
目标 单继承 多继承 面向对象三大特性 1,封装 根据 职责 将 属性 和 方法 封装 到以抽象的 类 中 2,继承 实现代码的重用,相同的代码不需要重复的缩写 3,多态 不同的对象调用相同的方法,产 ...
- python面向对象继承_四. python面向对象(继承)
一. 继承 class A:pass #父类 基类 超类 class B:pass #父类 基类 超类 class A_son(A,B): pass #子类 派生类 class AB_son(A):p ...
- Python基础——继承、多态
文章目录 一.slots 二.私有属性和私有方法 三.继承 1.私有属性.私有方法 2.继承的特点(多层继承) 3.新式类和经典类 四.方法的重写 五.多态 一.slots __slots__属性对应 ...
最新文章
- valid Palindrome -- leetcode
- apache2.2:使一个目录允许执行cgi程序
- [转]最常用的15大Eclipse开发快捷键技巧
- 苹果Mac仿windows10任务栏工具:​​​​​​​​uBar
- c# 保存数据到txt (追加)
- 区块链 什么是RLP编码
- python判断整数是否对称_刷题系列 - Python判断是否镜像对称二叉树
- python机器学习之物体识别
- java 汉字 正则_java正则表达式验证汉字
- Axure原型设计介绍
- HTML头部文档相关标记,html头部基本标记详解
- c语言公历转农历程序,用c如何编写 农历转换成公历
- MySQL传统无损同步
- 思科模拟器启用CHAP协议
- 苹果手机热点连上不能上网_「手机自学维修教程」苹果6plus手机屏幕触摸不能用的通病分析...
- php用代码写的三行情书,三行情书经典语录_最美的三行情书(两行泪,一段情)
- 抖音上超火系列的透明头像是怎么弄的?操作原来如此简单
- JVM、DVM(Dalvik VM)和ART虚拟机的区别
- 尚在人间,何处不青春
- 嵌入式linux开发环境搭建(VMware16.0.0+Ubuntu16.04.3_X64)