python进阶03 继承

一、继承

  课堂练习:假设你正在参与一个魔幻类角色游戏的开发,公司需要腻味这个游戏设计两个角色的类:

  a、剑士

    属性:1、角色名;2、角色等级;3、生命值;4、攻击力

    行为:物理攻击

  b、法师

    属性:1、角色名;2、角色等级;3、生命值;4、法术强度

    行为:1、法术攻击;2、治疗

  1. #首先定义一个剑士类
  2. class SwordsMan:#定义一个剑士类
  3. def __init__(self,name,lever,blood): #初始化剑士的名字,等级,血量
  4. self.name=name
  5. self.lever=level
  6. self.blood=blood
  7.  
  8. def fight(self): #行为函数 攻击方式:物理攻击
  9. print('物理输出')
  10.  
  11. def __repr__(self): #str没有的时候会找repr
  12. return '{cls}{name}{level}{blood}'.format(cls=__class__.__name__,name=self.name,level=self.level,blood=self.blood) #cls=__class__.__name__表示不管当前是哪个类,用这种方法就可以输出类名(好处在于不用指定类名,让系统自己算出自己的类名)
  1. #然后定义一个法师类
  2. class Magician:#定义一个法师类
  3. def __init__(self,name,lever,blood): #初始化剑士的名字,等级,血量
  4. self.name=name
  5. self.lever=level
  6. self.blood=blood
  7.  
  8. def fight(self): #行为函数 攻击方式:物理攻击
  9. print('法术攻击')
  10.  
  11. def cure(self):#行为函数 治疗
  12. print('治疗')
  13.  
  14. def __repr__(self): #str没有的时候会找repr
  15. return '{cls}{name}{level}{blood}'.format(cls=__class__.__name__,name=self.name,level=self.level,blood=self.blood)

  两个类中有大量重复的代码,是否可以只写一次(两个类之间有交集)

  剑士和法师都是角色,那么我们可以定义一个剑士和法师都隶属的角色类

  1. class Role:#
  2. def __init__(self,name,lever,blood):
  3. self.name=name
  4. self.lever=level
  5. self.blood=blood
  6.  
  7. def fight(self):
  8. raise NotImplementedError('攻击方式没有实现')#raise:自己丢出异常(认为异常/自己丢出异常);NotImplementedError:表示必须要在子类中去实现,Not表示没有 implemented表示实现
  9.  
  10. def __repr__(self):
  11. return '{cls}{name}{level}{blood}'.format(cls=__class__.__name__,name=self.name,level=self.level,blood=self.blood)

  然后就是继承,就是从角色类中派生(也就是继承)出各自的类

  1. class SwordsMan(Role): #如果什么都不写,就是跟父类Role一模一样
  2. pass
  3.  
  4. #剑士类
  5.  
  6. class SwordsMan(Role):
  7. def init(self,name,level,blood,attack_power):
  8. Role.__init__(self,name,level,blood) #这样手动调一次父类中已经定义的东西,公共的部分父类帮你初始化,子类的部分自己定义
  9. self.attack_power=attack_power
  10.  
  11. def fight(self):#父类里面有的,子类里面再写一次,叫做重写
  12. print('物理攻击')
  13.  
  14. #同理 法师
  15. class Mgician(Role):
  16. def init(self,name,level,blood,attack_power):
  17. Role.__init__(self,name,level,blood)
  18. self.magic_power=magic_power
  19.  
  20. def fight(self):
  21. print('魔法攻击')
  22.  
  23. def cure(self):
  24. print('治疗')

  继承搜索

  1. #访问类的属性和方法-->类 (如果找不到,转到其父类中查找) -->直接基类(如果再找不到,转到其父类的父类中去查找)-->间接基类
  2.  
  3. #所以继承不是变量空间的复制
  4.  
  5. #属性查找
  6. class Role:
  7. pass
  8.  
  9. class MyRole(Role):
  10. pass
  11.  
  12. print(MyRole.__dict__) #查找MyRole
  13.  
  14. #在子类中查找到了init,父类中的init就会被屏蔽

  关于重用父类的init

  1. class SwordsMan(Role):
  2.  
  3. def init(self,name,level,blood,attack_power):#子类中查找的self是剑士的实例
  4. Role.__init__(self,name,level,blood) #在父类中查找出的self也是剑士的实例
  5. self.attack_power=attack_power
  6.  
  7. #相当于
  8. def __init__(self,name,level,blood,attack_power):
  9. self.name=name
  10. self.level=level
  11. self.blood=blood
  12. self.attack_power=attack_power

  顶级基类object:所有类最终的父类,类似于树的跟

  1. #假如我拿到了别人写的库或者框架
  2. #人家肯定用到了面向对象,肯定会有继承
  3. #我正在用这个类,我想了解他的继承关系,想知道它继承于什么类
  4.  
  5. print(Magician.__bases__) #输出(Role)查找Magician类继承于什么类

  继承的意义:重用代码,方便代码的管理和修改

二、多重继承

  如果有多个基类,有同名属性和方法,应该如何选择

  1. class D:
  2. pass
  3.  
  4. class E:
  5. pass
  6.  
  7. class C:
  8. pass
  9.  
  10. class B(D,E): #B继承于D,E
  11. pass
  12.  
  13. class A(B,C):
  14. pass

  1. #到底是广度查找(A B C A E)还是(A B D E C)
  2. #不是以上两种方法,而是MRO-C3算法
  3.  
  4. print(A.mro()) #mro方法,是在类里面的,它会自己计算出,搜索顺序

  C3算法会由于冲突导致不能继承

  1. class A:
  2. pass
  3.  
  4. class B:
  5. pass
  6.  
  7. class C(A,B):
  8. pass
  9.  
  10. class D(B,A):
  11. pass
  12.  
  13. class E(C,D):
  14. pass
  15.  
  16. #会报错,这个顺序是违反了C3规则
  17. #对于C而言,A比B优先;对于D而言,B比A优先,而E继承C和D就爆炸了

  鸭子类型:如果走起来或叫起来像鸭子,那么你就是鸭子

  1. class SwordsMan(Role):
  2. def init(self,name,level,blood,attack_power):
  3. Role.__init__(self,name,level,blood)
  4. self.attack_power=attack_power
  5.  
  6. def fight(self):
  7. print('物理攻击')
  8.  
  9. #展示出攻击的效果(这件事不属于任何一个角色)
  10. #写一个函数
  11. def draw_fight(role): #鸭子类型体现出来的是,一个函数关心的不是类型,而是行为
  12. print('role',end='')
  13. role.fight() #要求你传入一个Role,传入剑士的实例可以吗?可以。因为剑士也是角色,我不管你是什么类,只要你有fight方法,我就认为你是个角色
  14.  
  15. s=SwordsMan('A',18,3000,8888)
  16. draw_fight(a) #输出role 物理攻击
  17.  
  18. class Girlfriend:
  19.  
  20. def __init__(self,name):
  21. self.name=name
  22.  
  23. def fight(self):
  24. print('拔电源攻击')
  25.  
  26. g=Girlfriend('xiaopo')
  27. draw_fight()#输出role 拔电源攻击
  28.  
  29. 综上鸭子类型,只要你有这个行为,你就是鸭子

  基于多继承的Mix-in设计模式

  1. #单继承就是分类思想,爸爸就只有一个,往下无限繁衍
  2. #多继承就是拼积木(Mix-in)思想
  3. #注意:一般“Mix-in”是继承的终点,只继承一次,通俗的讲:就是胳膊有人这个爸爸,脑袋有人这个爸爸,腿有人这个爸爸,这三个最好不要有其他爸爸,人上面也别在生出个爸爸

三、super函数

 更加优雅地调用父类中的方法

  1. #在角色和剑士中间加了两个分类:英雄和NPC,怎么办
  2. class Hero:
  3. pass
  4.  
  5. class NPC:
  6. pass
  7.  
  8. class SwordsMan(Role):
  9. def init(self,name,level,blood,attack_power):
  10. Role.__init__(self,name,level,blood) #如果我在做游戏,Role只是角色,角色又可以分为英雄和NPC。这便需要将Role变为Hero,也就是在调用父类方法的时候要变为Hero了,上面类中的Role也要换,这样很不优雅
  11. self.attack_power=attack_power
  12.  
  13. 改变为下面这个即可:
  14. class SwordsMan(Role):
  15. def init(self,name,level,blood,attack_power):
  16. super().__init__(name,level,blood) #将前面的Role变为super,后面的self去掉,系统会自动查找父类
  17. self.attack_power=attack_power

python进阶03 继承的更多相关文章

  1. Python面向对象03 /继承

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

  2. python进阶03

    进程线程不管哪门语言都是一块可以被重视的方向,下面一起学习学习python中的进程,线程 1.进程线程区别 通俗解释:一个程序QQ的运行就是一个进程运行:QQ中打开多个页面互不影响可以同时操作的每个页 ...

  3. Python进阶-XVI 继承 单继承 多继承

    一.初识继承 1.引入继承 class A(object): pass # 父类,基类,超类 class B: pass # 父类,基类,超类 class A_son(A, B): pass # 子类 ...

  4. Python进阶03 模块

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们之前看到了函数和对象.从本质上来说,它们都是为了更好的组织已经有的程序,以方便 ...

  5. Python进阶-继承中的MRO与super

    Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...

  6. python进阶(5):组合,继承

    前两天我们认识了面向对象也对面向对象有了初步的认识今天我们先会说一点组合的进阶,今天重点是继承. 一.组合 组合只有一个例子因为组合只作为上一章的补充内容 #老师 课程 生日 class Course ...

  7. Python类的继承(进阶5)

    转载请标明出处: http://www.cnblogs.com/why168888/p/6411918.html 本文出自:[Edwin博客园] Python类的继承(进阶5) 1. python中什 ...

  8. Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)

    Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装:            将一些东西封装到一个地方,你还可以取出来( ...

  9. Python进阶(十五)----面向对象之~继承(单继承,多继承MRO算法)

    Python进阶(十五)----面向对象之~继承 一丶面向对象的三大特性:封装,继承,多态 二丶什么是继承 # 什么是继承 # b 继承 a ,b是a的子类 派生类 , a是b的超类 基类 父类 # ...

随机推荐

  1. python做简易记事本

    以下内容参考<辛星tkinter教程第二版>: from tkinter import * from tkinter.filedialog import * from tkinter.me ...

  2. BZOJ 1640 [Usaco2007 Nov]Best Cow Line 队列变换:贪心【字典序最小】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1640 题意: 给你一个长度为n的字符串. 你可以将原串的首字母或尾字母移动到新串的末尾. ...

  3. CI框架上传csv文件

    今天遇到在用CI框架上传csv文件时报错问题: The filetype you are attempting to upload is not allowed. 是类型不允许,想到CI框架的conf ...

  4. 存储过程之rowtype 使用

    CREATE OR REPLACE PROCEDURE "DYLYLQX_SC_BA_1" (YWID IN VARCHAR2, FLAG OUT VARCHAR2) IS V_R ...

  5. python之网络编程(概述及SOCKET)

    概述(TCP/IP协议是一个协议族): TCP/IP 协议按照四层怎么划分:链路层,网络层,传输层,应用层(实际上是四层) TCP/IP 协议按照七层怎么划分:物理层,数据链路层,网络层,传输层,会话 ...

  6. 使用ubuntu自带的Remmina Remote Desktop Client远程登录服务器配置

    1.配置:点击new , 配置服务器ip地址.名称.密码 2.打开本机终端执行一下命令: echo xfce4-session>.session echo xfce4-session>.x ...

  7. bzoj 1510 [POI2006]Kra-The Disks——思路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1510 #include<iostream> #include<cstdio ...

  8. POJ1986(LCA应用:求两结点之间距离)

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 11304   Accepted: 3985 ...

  9. SQL Server 将查询的结果生成insert语句

    1.将查询的结果插入到一张新表(yangTest 表系统会自动生成)select Area, District, RoadName, StationName, PathDirection, Stati ...

  10. MFS安装配置使用

    MFS server:192.168.209.18groupadd mfsuseradd -g mfs mfscd /usr/srctar xzvf mfs-1.6.27-5.tar.gzcd mfs ...