一、继承

继承是一种创建新的类的方式,在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面向对象之继承与派生的更多相关文章

  1. Python面向对象编程——继承与派生

    Python面向对象编程--继承与派生 一.初始继承 1.什么是继承 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题. 继承是一种创 ...

  2. python 面向对象之继承与派生

    一:初识继承 1,什么是继承? 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题 继承是一种创建新类的方式,在python中,新建的类 ...

  3. Python面向对象03 /继承

    Python面向对象03 /继承 目录 Python面向对象03 /继承 1. 初识继承 2. 单继承 3. 多继承 4. 总结 1. 初识继承 概念:专业角度:如果B类继承A类,B类就称为子类,派生 ...

  4. Python 面向对象编程 继承 和多态

    Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...

  5. python面向对象(封装,继承,多态)

    python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...

  6. python之旅:面向对象之继承与派生

    一 初识继承 编写类时,并非总要从空白开始.如果你要编写的类正好是另一个现成类的特殊版本,可使用继承来减少代码冗余,子类会“遗传”父类的属性,从而解决代码重用问题 什么是继承 继承是一种创建新类的方式 ...

  7. python面向对象编程 继承 组合 接口和抽象类

    1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均用点来访问自己的 ...

  8. python面向对象的继承-组合-02

    *面向对象(OOP)的三大特征:**# 封装.继承.多态 继承 什么是继承 继承:# 是一种关系,描述两个对象之间什么是什么的什么的关系 例如:麦兜.佩奇.猪猪侠.猪刚鬣,都是猪 为什么要使用继承 继 ...

  9. python面向对象之继承/多态/封装

    老师说,按继承/多态/封装这个顺序来讲. 子类使用父类的方法: #!/usr/bin/env python # coding:utf-8 class Vehicle: def __init__(sel ...

随机推荐

  1. 失败的尝试,使用继承扩展数组,以及ES6的必要性

    我们都知道直接在原生对象上扩展对象是很不好的.所以prototype这样的库广受非议. 一些库,比如lodash采用了工具包形式的扩展方式,绕开了对象的继承. 由于es6的class的出现,我尝试以A ...

  2. 「暑期训练」「Brute Force」 Optimal Point on a Line (Educational Codeforces Round 16, B)

    题意 You are given n points on a line with their coordinates $x_i$. Find the point x so the sum of dis ...

  3. 08-Mysql数据库----完整性约束

    总结:      1,not null 不能插入空,不设置可空       2,unique  单列唯一 create table department(name char(10) unique); ...

  4. [Node] Agenda 中文文档 定时任务调度系统[基础篇]

    Agenda简介 使用步骤概述 步骤详述 初始化 定义任务 参数说明: 配置任务 参数说明 设置监听 注意事项 Agenda简介 Agenda是一个定时任务管理模块,它将node中的定时任务存储在数据 ...

  5. CentOS 6.5 下安装redis

    1.登录虚拟机后,直接输入命令:yum -y install redis 会出现一个错误: 是因为少了epel源, 2.运行:yum -y install epel-release 最后出现 Comp ...

  6. POJ 2161 Chandelier(动态规划)

    Description Lamps-O-Matic company assembles very large chandeliers. A chandelier consists of multipl ...

  7. IDEA无法新建GUI Form文件

    因为最近想开发一个IDEA的插件,所以在开发的过程中就需要创建Swing GUI Form文件.但是在项目中右键New中始终就是没有“GUI Form”这个选项,然后自己琢磨寻思着是不是没有启用Swi ...

  8. C++ 点

    2017/12/23 scoped_ptr类型的指针,只能在一个namespace中使用 1) 怎么查看元素在set中是否存在 1) istringstream类用于执行C++风格的串流的输入操作. ...

  9. 算法(5)Jump Game

    题目:非负数的数组,每个数组元素代表这你能最大跨越多少步,初始在0的位置,问,能不能正好调到数组的最后一位! https://leetcode.com/problems/jump-game/#/des ...

  10. hadoop 集群常见错误解决办法

    hadoop 集群常见错误解决办法 hadoop 集群常见错误解决办法: (一)启动Hadoop集群时易出现的错误: 1.   错误现象:Java.NET.NoRouteToHostException ...