python面向对象之继承与派生
一、继承
继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类。
python中类的继承分为:单继承和多继承,如果是多继承的话,继承顺序有深度和广度2种
示例:
class ParentClass1: #定义父类
pass class ParentClass2: #定义父类
pass class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
pass class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
pass
查看继承:
示例:
>>> SubClass1.__bases__
(<class '__main__.ParentClass1'>,)
>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。
示例:
>>> ParentClass1.__bases__
(<class 'object'>,)
>>> ParentClass2.__bases__
(<class 'object'>,)
继承同时具有两种含义
含义一.继承基类的方法,并且做出自己的改变或者扩展(代码重用)
含义二.声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法
继承最大的好处是减少重用的代码
示例:
class hero:#父类
def __init__(self,nickname,aggressivity=58,life_value=455,):
self.nickname=nickname
self.aggressivity=aggressivity
self.life_value=life_value def attack(self,enemy):
enemy.life_value-=self.aggressivity
print(enemy.life_value)
class Garen(hero):#子类继承父类hero
camp='Demacia'#这个英雄人物全部继承父类的内容,只有阵营不一样
class Riven(hero):#子类继承父类hero
#这个英雄人物全部继承父类的内容,只有阵营不一样
camp='Noxus'
g1=Garen("无敌")
# print(g1)
r1=Riven("萌萌")
g1.attack(r1)#攻击萌萌
执行结果是:
397
上述代码都继承了hero英雄的类,所以有类里面共同的属性,极大的减少了代码的重用性
二、派生
然而,继承有时在应用场景中并不能满足需求,有时子类也需要添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。所以这一概念就相当于是“派生”
派生:首先继承父类的,再定义自己的构造方法
用上述例子在此示例:
class hero:#父类
def __init__(self,nickname,aggressivity=58,life_value=455,):
self.nickname=nickname
self.aggressivity=aggressivity
self.life_value=life_value def attack(self,enemy):
enemy.life_value-=self.aggressivity
print(enemy.life_value,'Hero attack') class Garen(hero):#子类继承父类hero
camp='Demacia'
def __init__(self,nickname,aggressivity=58,life_value=455,money=100):
hero.__init__(self,nickname,aggressivity=58,life_value=455,)#调用父类的函数__init__(self,nickname,aggressivity=58,life_value=455,)
self.money=money#派生出自己的新特色功能出来
def attack(self,enemy,tiao):
hero.attack(self,enemy)#调用父类的函数attack(self,enemy)
self.tiao=tiao#派生出自己的新特色功能出来
print('from garen attack')
def file(self):#新加技能
print("%s is filing"%self.nickname) class Riven(hero):#子类继承父类hero
#这个英雄人物全部继承父类的内容,只有阵营不一样
camp='Noxus' g1=Garen("无敌")
g1.file()#打印新加的技能
print(g1.money)#打印新加的money值
# print(g1)
r1=Riven("萌萌")
g1.attack(r1,"enemy")#攻击萌萌
g1.attack(r1,"enemy")#攻击萌萌
其执行结果是:
无敌 is filing
100
397 Hero attack
from garen attack
339 Hero attack
from garen attack
关于继承的顺序:
继承在Python不同版本中是有区别的。
python3: 新式类(广度优先)
pyhon2: 新式类(广度优先)与经典类(深度优先)
示例说明:
新式类的继承顺序如下图:(python2和python3中都一样)
用代码是:
class A:
def __init__(self):
print('A的构造方法')
class B(A):
def __init__(self):
print('B的构造方法')
pass
class C(A):
def __init__(self):
print('C的构造方法')
pass
class D(B):
def __init__(self):
print('D的构造方法')
pass
class E(C):
def __init__(self):
print('E的构造方法')
pass class F(D,E):
def __init__(self):
print('F的构造方法')
pass
f1=F()#实例化触发运行
执行顺序是:
F——》D——》B——》E——》C——》A——》object
经典类的实现是:(仅仅只有Python2中有)
经典类的继承顺序如下图:(深度优先)
用代码是实现是:
#python2中经典类的继承,在查找属性时遵循:深度优先
class A:
# def test(self):
# print('from A')
pass
class B(A):
# def test(self):
# print('from B')
pass
class C(A):
# def test(self):
# print('from C')
pass
class D(B):
# def test(self):
# print('from D')
pass class E(C):
# def test(self):
# print('from E')
pass
class F(D,E):
# def test(self):
# print('from F')
pass
f1=F()
f1.test() # F->D->B->A->E->C
执行顺序是:
F->D->B->A->E->C
查看python如何实现的继承(使用类名.mor()查看)
python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如
>>> F.mro() #等同于F.__mro__
[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
总结:
为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:
1.子类会先于父类被检查
2.多个父类会根据它们在列表中的顺序被检查
3.如果对下一个类存在两个合法的选择,选择第一个父类
python面向对象之继承与派生的更多相关文章
- Python面向对象编程——继承与派生
Python面向对象编程--继承与派生 一.初始继承 1.什么是继承 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题. 继承是一种创 ...
- python 面向对象之继承与派生
一:初识继承 1,什么是继承? 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题 继承是一种创建新类的方式,在python中,新建的类 ...
- Python面向对象03 /继承
Python面向对象03 /继承 目录 Python面向对象03 /继承 1. 初识继承 2. 单继承 3. 多继承 4. 总结 1. 初识继承 概念:专业角度:如果B类继承A类,B类就称为子类,派生 ...
- Python 面向对象编程 继承 和多态
Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...
- python面向对象(封装,继承,多态)
python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...
- python之旅:面向对象之继承与派生
一 初识继承 编写类时,并非总要从空白开始.如果你要编写的类正好是另一个现成类的特殊版本,可使用继承来减少代码冗余,子类会“遗传”父类的属性,从而解决代码重用问题 什么是继承 继承是一种创建新类的方式 ...
- python面向对象编程 继承 组合 接口和抽象类
1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均用点来访问自己的 ...
- python面向对象的继承-组合-02
*面向对象(OOP)的三大特征:**# 封装.继承.多态 继承 什么是继承 继承:# 是一种关系,描述两个对象之间什么是什么的什么的关系 例如:麦兜.佩奇.猪猪侠.猪刚鬣,都是猪 为什么要使用继承 继 ...
- python面向对象之继承/多态/封装
老师说,按继承/多态/封装这个顺序来讲. 子类使用父类的方法: #!/usr/bin/env python # coding:utf-8 class Vehicle: def __init__(sel ...
随机推荐
- Qt 报错LINK2019:无法解析的外部符号
这里用的都是Qt 自己的东西,但是还是抱错,所以怀疑是没有包含进去,尝试了清理项目,重新编译等,还是不行 用到一个最好的办法,就是把构建的文件夹整个删除,在重新编译就可以了 如图所示,把debug和r ...
- jmeter的基本使用过程
jmeter的基本使用过程 接下来几周,我将通过视频的方式,录制下来jmeter的基本用法,方便大家参考学习 可能导图会随时调整
- python 学习总结----正则表达式
正则表达式 应用场景 - 特定规律字符串的查找,切割,替换 - 邮箱格式:URl,IP地址等的校验 - 爬虫项目中,特定内容的提取 使用原则 - 只要使用字符串等函数能解决的问题,就不要使用正则 - ...
- 异常处理中try,else,finally含有return的情况解析
直接看代码,拿到你的py下运行测试一下就 明白了. 例一: def f(): try: print() finally: print() print(f()) # 若注释掉finally内的retur ...
- CSP201604-1:折点计数
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...
- Mybatis 异常记录(1): Invalid bound statement (not found)
错误信息: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.pingan.cr ...
- 对 vscode 自动格式化的结果不太满意,我们该如何自己调整直至自己满意为止
前提概述 采用vue-cli 3.0自动生成vue项目,选了ESlint+Prettier,在写request.js的时候,顺手用vscode右击格式化文件(Alt+Shift+F),一下子报了8个问 ...
- LCA(最近公共祖先)——离线 Tarjan 算法
tarjan算法的步骤是(当dfs到节点u时):1 在并查集中建立仅有u的集合,设置该集合的祖先为u1 对u的每个孩子v: 1.1 tarjan之 1.2 合并v到父节点u的集合,确保集合的祖 ...
- 深度优先搜索(DFS),逃离迷宫
[原创] 今天来说说深度优先搜索,深度优先是图论中的内容,大意是从某一点出发,沿着一个方向搜索下去,并伴随着有回退的特点,通常用来判断某一解是否存在,不用来寻找最优解:这里来看一个非常有意思的题目: ...
- lintcode-108-分割回文串 II
108-分割回文串 II 给定一个字符串s,将s分割成一些子串,使每个子串都是回文. 返回s符合要求的的最少分割次数. 样例 比如,给出字符串s = "aab", 返回 1, 因为 ...