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 ...
随机推荐
- 树莓派i2c功能
默认i2c是关闭的,用raspi-config 命令,会弹出一个配置框图 选择enable i2c就可以了 reboot之后 没有在/dev/目录下发现i2c-x的设备,这个时候需要做以下操作 1.添 ...
- wampserver 安装后 启动失败的解决方法
安装后启动, 显示 发生未知的异常 wampmanager.exe .... 解决方法 === 其实下载页面说了,先下载 vc的运行库,页面上有链接, 他给的是vc10的,我按照做,失败 查了无数资 ...
- Flask 学习笔记(二):RESTful API
概括 URL:需要操作的对象,也就是资源 HTTP method:我要对该对象做什么(POST 增.DELETE 删.GET 查.PUT 和 PATCH 改) HTTP status code:操作的 ...
- Spring 学习笔记(八)—— 注解使用整合
@Autowired —— 自动装配 需先在配置文件中,配置一个org.springframework.beans.factory.annotation. AutowiredAnnotationBe ...
- python中locals和globals函数
参考:http://www.cnblogs.com/wanxsb/archive/2013/05/07/3064783.html Python有两个内置的函数,locals() 和globals(), ...
- ssh问题_2
前一段时间配置hadoop集群环境,发现一个现象,教程中的命令形式是ssh hostname,当然这个hostname应该是在ssh发起者的hosts文件中和相应的IP对应:现在问题来了: 我用的是m ...
- SQL Server 监测语句
qs.creation_time, last_execution_time, total_physical_reads, total_logical_reads, total_logical_writ ...
- [C/C++] “箭头(->)”和“点号(.)”的区别
转自:http://blog.csdn.net/gyymen/article/details/4962873 首先介绍一下C++中的结构.对于一个结构: struct MyStruct { int m ...
- 51nod 1680区间求和 (dp+树状数组/线段树)
不妨考虑已知一个区间[l,r]的k=1.k=2....k=r-l+1这些数的答案ans(只是这一个区间,不包含子区间) 那么如果加入一个新的数字a[i](i = r+1) 则新区间[l, i]的答案为 ...
- [洛谷P1892]团伙
题目大意:有n个人,关系为:朋友的朋友是朋友,敌人的敌人是朋友.如果是朋友就在一个团队内,是敌人就不在,现在给出一关系,问最多有多少团伙.题解:并查集,建反集,如果是朋友,就把他们的并查集合并:如果是 ...