python进阶03 继承
python进阶03 继承
一、继承
课堂练习:假设你正在参与一个魔幻类角色游戏的开发,公司需要腻味这个游戏设计两个角色的类:
a、剑士
属性:1、角色名;2、角色等级;3、生命值;4、攻击力
行为:物理攻击
b、法师
属性:1、角色名;2、角色等级;3、生命值;4、法术强度
行为:1、法术攻击;2、治疗
#首先定义一个剑士类
class SwordsMan:#定义一个剑士类
def __init__(self,name,lever,blood): #初始化剑士的名字,等级,血量
self.name=name
self.lever=level
self.blood=blood def fight(self): #行为函数 攻击方式:物理攻击
print('物理输出') def __repr__(self): #str没有的时候会找repr
return '{cls}{name}{level}{blood}'.format(cls=__class__.__name__,name=self.name,level=self.level,blood=self.blood) #cls=__class__.__name__表示不管当前是哪个类,用这种方法就可以输出类名(好处在于不用指定类名,让系统自己算出自己的类名)
#然后定义一个法师类
class Magician:#定义一个法师类
def __init__(self,name,lever,blood): #初始化剑士的名字,等级,血量
self.name=name
self.lever=level
self.blood=blood def fight(self): #行为函数 攻击方式:物理攻击
print('法术攻击') def cure(self):#行为函数 治疗
print('治疗') def __repr__(self): #str没有的时候会找repr
return '{cls}{name}{level}{blood}'.format(cls=__class__.__name__,name=self.name,level=self.level,blood=self.blood)
两个类中有大量重复的代码,是否可以只写一次(两个类之间有交集)
剑士和法师都是角色,那么我们可以定义一个剑士和法师都隶属的角色类
class Role:#
def __init__(self,name,lever,blood):
self.name=name
self.lever=level
self.blood=blood def fight(self):
raise NotImplementedError('攻击方式没有实现')#raise:自己丢出异常(认为异常/自己丢出异常);NotImplementedError:表示必须要在子类中去实现,Not表示没有 implemented表示实现 def __repr__(self):
return '{cls}{name}{level}{blood}'.format(cls=__class__.__name__,name=self.name,level=self.level,blood=self.blood)
然后就是继承,就是从角色类中派生(也就是继承)出各自的类
class SwordsMan(Role): #如果什么都不写,就是跟父类Role一模一样
pass #剑士类 class SwordsMan(Role):
def init(self,name,level,blood,attack_power):
Role.__init__(self,name,level,blood) #这样手动调一次父类中已经定义的东西,公共的部分父类帮你初始化,子类的部分自己定义
self.attack_power=attack_power def fight(self):#父类里面有的,子类里面再写一次,叫做重写
print('物理攻击') #同理 法师
class Mgician(Role):
def init(self,name,level,blood,attack_power):
Role.__init__(self,name,level,blood)
self.magic_power=magic_power def fight(self):
print('魔法攻击') def cure(self):
print('治疗')
继承搜索
#访问类的属性和方法-->类 (如果找不到,转到其父类中查找) -->直接基类(如果再找不到,转到其父类的父类中去查找)-->间接基类 #所以继承不是变量空间的复制 #属性查找
class Role:
pass class MyRole(Role):
pass print(MyRole.__dict__) #查找MyRole #在子类中查找到了init,父类中的init就会被屏蔽
关于重用父类的init
class SwordsMan(Role):
def init(self,name,level,blood,attack_power):#子类中查找的self是剑士的实例
Role.__init__(self,name,level,blood) #在父类中查找出的self也是剑士的实例
self.attack_power=attack_power
#相当于
def __init__(self,name,level,blood,attack_power):
self.name=name
self.level=level
self.blood=blood
self.attack_power=attack_power
顶级基类object:所有类最终的父类,类似于树的跟
#假如我拿到了别人写的库或者框架
#人家肯定用到了面向对象,肯定会有继承
#我正在用这个类,我想了解他的继承关系,想知道它继承于什么类 print(Magician.__bases__) #输出(Role)查找Magician类继承于什么类
继承的意义:重用代码,方便代码的管理和修改
二、多重继承
如果有多个基类,有同名属性和方法,应该如何选择
class D:
pass class E:
pass class C:
pass class B(D,E): #B继承于D,E
pass class A(B,C):
pass

#到底是广度查找(A B C A E)还是(A B D E C)
#不是以上两种方法,而是MRO-C3算法 print(A.mro()) #mro方法,是在类里面的,它会自己计算出,搜索顺序
C3算法会由于冲突导致不能继承
class A:
pass class B:
pass class C(A,B):
pass class D(B,A):
pass class E(C,D):
pass #会报错,这个顺序是违反了C3规则
#对于C而言,A比B优先;对于D而言,B比A优先,而E继承C和D就爆炸了

鸭子类型:如果走起来或叫起来像鸭子,那么你就是鸭子
class SwordsMan(Role):
def init(self,name,level,blood,attack_power):
Role.__init__(self,name,level,blood)
self.attack_power=attack_power def fight(self):
print('物理攻击') #展示出攻击的效果(这件事不属于任何一个角色)
#写一个函数
def draw_fight(role): #鸭子类型体现出来的是,一个函数关心的不是类型,而是行为
print('role',end='')
role.fight() #要求你传入一个Role,传入剑士的实例可以吗?可以。因为剑士也是角色,我不管你是什么类,只要你有fight方法,我就认为你是个角色 s=SwordsMan('A',18,3000,8888)
draw_fight(a) #输出role 物理攻击 class Girlfriend: def __init__(self,name):
self.name=name def fight(self):
print('拔电源攻击') g=Girlfriend('xiaopo')
draw_fight()#输出role 拔电源攻击 综上鸭子类型,只要你有这个行为,你就是鸭子
基于多继承的Mix-in设计模式
#单继承就是分类思想,爸爸就只有一个,往下无限繁衍
#多继承就是拼积木(Mix-in)思想
#注意:一般“Mix-in”是继承的终点,只继承一次,通俗的讲:就是胳膊有人这个爸爸,脑袋有人这个爸爸,腿有人这个爸爸,这三个最好不要有其他爸爸,人上面也别在生出个爸爸
三、super函数
更加优雅地调用父类中的方法
#在角色和剑士中间加了两个分类:英雄和NPC,怎么办
class Hero:
pass class NPC:
pass class SwordsMan(Role):
def init(self,name,level,blood,attack_power):
Role.__init__(self,name,level,blood) #如果我在做游戏,Role只是角色,角色又可以分为英雄和NPC。这便需要将Role变为Hero,也就是在调用父类方法的时候要变为Hero了,上面类中的Role也要换,这样很不优雅
self.attack_power=attack_power 改变为下面这个即可:
class SwordsMan(Role):
def init(self,name,level,blood,attack_power):
super().__init__(name,level,blood) #将前面的Role变为super,后面的self去掉,系统会自动查找父类
self.attack_power=attack_power
python进阶03 继承的更多相关文章
- Python面向对象03 /继承
Python面向对象03 /继承 目录 Python面向对象03 /继承 1. 初识继承 2. 单继承 3. 多继承 4. 总结 1. 初识继承 概念:专业角度:如果B类继承A类,B类就称为子类,派生 ...
- python进阶03
进程线程不管哪门语言都是一块可以被重视的方向,下面一起学习学习python中的进程,线程 1.进程线程区别 通俗解释:一个程序QQ的运行就是一个进程运行:QQ中打开多个页面互不影响可以同时操作的每个页 ...
- Python进阶-XVI 继承 单继承 多继承
一.初识继承 1.引入继承 class A(object): pass # 父类,基类,超类 class B: pass # 父类,基类,超类 class A_son(A, B): pass # 子类 ...
- Python进阶03 模块
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们之前看到了函数和对象.从本质上来说,它们都是为了更好的组织已经有的程序,以方便 ...
- Python进阶-继承中的MRO与super
Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...
- python进阶(5):组合,继承
前两天我们认识了面向对象也对面向对象有了初步的认识今天我们先会说一点组合的进阶,今天重点是继承. 一.组合 组合只有一个例子因为组合只作为上一章的补充内容 #老师 课程 生日 class Course ...
- Python类的继承(进阶5)
转载请标明出处: http://www.cnblogs.com/why168888/p/6411918.html 本文出自:[Edwin博客园] Python类的继承(进阶5) 1. python中什 ...
- Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)
Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: 将一些东西封装到一个地方,你还可以取出来( ...
- Python进阶(十五)----面向对象之~继承(单继承,多继承MRO算法)
Python进阶(十五)----面向对象之~继承 一丶面向对象的三大特性:封装,继承,多态 二丶什么是继承 # 什么是继承 # b 继承 a ,b是a的子类 派生类 , a是b的超类 基类 父类 # ...
随机推荐
- Linux中常用文件传输命令及使用方法
sftp sftp即Secure Ftp 是一个基于SSH安全协议的文件传输管理工具.由于它是基于SSH的,会在传输过程中对用户的密码.数据等敏感信息进行加密,因此可以有效的防止用户信息在传输的过程中 ...
- BZOJ 2442 [Usaco2011 Open]修剪草坪:单调队列优化dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2442 题意: 有n个数a[i]从左到右排成一排. 你可以任意选数,但是连续的数不能超过k个 ...
- Proftpd mysql认证配置文档
Proftpd mysql认证配置文档 ver1.0, 2012/09/25 一.下载安装proftp mysql 下载 wget http://cloud.github.com/downloads/ ...
- codeforces 651E E. Table Compression(贪心+并查集)
题目链接: E. Table Compression time limit per test 4 seconds memory limit per test 256 megabytes input s ...
- Posix线程编程指南(1)
这是一个关于Posix线程编程的专栏.作者在阐明概念的基础上,将向您详细讲述Posix线程库API.本文是第一篇将向您讲述线程的创建与取消. 一.线程创建 1.1 线程与进程相对进程而言,线程是一 ...
- kettle导数到user_用于left join_20160928
这篇博客主要是给mysql left join做铺垫,需要现在本地数据库创建一个users 数据表 然后去和 test_a03order表 left join 一.首先在local_db数据库先创建 ...
- ACM学习历程—HDU5418 Victor and World(动态规划 && 状压)
这个题目由于只有16个城市,很容易想到去用状压来保存状态. p[i][state]表示到i城市经过state状态的城市的最优值(state的二进制位每一位为1表示经过了该城市,否则没经过) 这样p[j ...
- DataGrid 滚动特定的行或者列
DataGrid 滚动特定的行或者列. DataGrid.ScrollIntoView Method (Object, DataGridColumn) .NET Framework 4.5 Silve ...
- ACM之Java技巧
一.Java之ACM注意点 关于四舍五入 小数保留几位: DecimalFormat df = new DecimalFormat("0.00"); String num = d ...
- C#开发Activex控件(转载别人的只为再看时方便放在自己里边了)
前言 ActiveX控件以前也叫做OLE控件,它是微软IE支持的一种软件组件或对象,可以将其插入到Web页面中,实现在浏览器端执行动态程序功能, 以增强浏览器端的动态处理能力.通常ActiveX控件都 ...