【一】什么是派生

  • 派生是指,子类继承父类,派生出自己的属性与方法,并且重用父类的属性与方法

【二】派生的方法

  • 子类可以派生出自己新的属性,在进行属性查找时,子类中的属性名会优先于父类被查找
  • 例如每个老师还有职称这一属性
  • 我们就需要在Teacher类中定义该类自己的__init__覆盖父类的
  • 当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。
class People:
school = "清华大学" def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age class Teacher(People):
# 派生:派生出自己新的属性,在进行属性查找时,子类中的属性名会优先于父亲被查找
def __init__(self, name, sex, age, title):
self.name = name
self.sex = sex
self.age = age
self.title = title def teach(self):
print('%s is teaching' % self.name) # 只会找自己类中的__init__,并不会自动调用父类的
obj = Teacher('zhang', 'melo', 10, '老师') print(obj.name, obj.sex, obj.age, obj.title)
# zhang melo 10 老师
  • 很明显子类Teacher中__init__内的前三行又是在写重复代码
  • 若想在子类派生出的方法内重用父类的功能,有两种实现方式

【1】指名道姓的调用某一个类的函数

class People:
school = "清华大学" def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age class Teacher(People):
# 派生 : 派生出自己新的属性,在进行属性查找时,子类中的属性名会优先于父类被查找
def __init__(self, name, sex, age, title):
# 直接调用 父类中的__init__的方法
# 调用的是函数,因而需要传入self
People.__init__(self, name, age, sex)
self.title = title def teach(self):
print('%s is teaching' % self.name) obj = Teacher('zhang', 'male', 18, '老师')
print(obj.name, obj.sex, obj.age, obj.title)
# zhang 18 male 老师

【2】超类(super())

  • 调用super()会得到一个特殊的对象
  • 该对象专门用来引用父类的属性
  • 且严格按照MRO规定的顺序向后查找
class People:
school = "清华大学" def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age class Teacher(People):
# 派生:派生出自己新的属性,在进行属性查找时,子类中的属性名会优先于父亲被查找
def __init__(self, name, sex, age, title):
# 直接调用 父类 中 的 __init__ 方法
# 调用的是绑定方法,因此会自动传入self,但是需要传入相应的参数
super().__init__(name, sex, age)
self.title = title def teach(self):
print('%s is teaching' % self.name) # 只会找自己类中的__init__,并不会自动调用父类的
obj = Teacher('zhang', 'melo', 10, '老师') print(obj.name, obj.sex, obj.age, obj.title)
# zhang melo 10 老师
  • 提示:在Python2中super的使用需要完整地写成super(自己的类名,self) ,而在python3中可以简写为super()。
  • 当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。
  • 只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次
  • 注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表

【3】小结

  • 这两种方式的区别是:

    • 方式一是跟继承没有关系的,而方式二的super()是依赖于继承的
    • 并且即使没有直接继承关系,super()仍然会按照MRO继续往后查找

【三】什么是组合

  • 在一个类中以另外一个类的对象作为数据属性,称为类的组合。

【四】组合的使用

  • 不同的是:

    • 继承是一种“是”的关系,比如老师是人、学生是人,当类之间有很多相同的之处,应该使用继承;
    • 而组合则是一种“有”的关系,比如老师有生日,老师有多门课程,当类之间有显著不同,并且较小的类是较大的类所需要的组件时,应该使用组合
class Course:
def __init__(self, name, period, price):
self.name = name
self.period = period
self.price = price def tell_info(self):
print(f'当前课程名字 {self.name} 当前课程周期 {self.period} 当前课程价格 {self.price}') class Date:
def __init__(self, year, mon, day):
self.year = year
self.mon = mon
self.day = day def tell_birth(self):
print(f'当前生日 {self.year} 年 {self.mon} 月 {self.day} 日') class People:
school = '清华大学' def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age # Teacher类基于继承来重用People的代码
# 基于组合来重用Date类和Course类的代码
class Teacher(People):
# 老师是人
def __init__(self, name, sex, age, title, year, mon, day):
super().__init__(name, age, sex)
# 老师有生日
self.birth = Date(year, mon, day)
# 老师有课程,可以在实例化后,往该列表中添加Course类的对象
self.courses = [] def teach(self):
print(f'当前老师正在授课 {self.name}') python = Course('python', '3mons', 3000.0)
linux = Course('linux', '5mons', 5000.0)
teacher1 = Teacher('dream', 'male', 18, '金牌讲师', 1987, 3, 23) # teacher1有两门课程
teacher1.courses.append(python)
teacher1.courses.append(linux) # 重用Date类的功能
teacher1.birth.tell_birth() # 重用Course类的功能
for obj in teacher1.courses:
obj.tell_info() # 当前生日 1987 年 3 月 23 日
# 当前课程名字 python 当前课程周期 3mons 当前课程价格 3000.0
# 当前课程名字 linux 当前课程周期 5mons 当前课程价格 5000.0
  • 此时对象teacher1集对象独有的属性、Teacher类中的内容、Course类中的内容于一身(都可以访问到),是一个高度整合的产物
  • 当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

【五】组合和继承的区别

  • 组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,

【1】继承的方式

  • 通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。
  • 当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人

【2】组合的方式

  • 用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...

Python面向对象之派生和组合的更多相关文章

  1. python 面向对象 继承 派生 组合

    具体参考博客:http://www.cnblogs.com/linhaifeng/articles/6182264.html#_label12 一.面向对象 面向对象:对象与对象之间的相互交互,不可预 ...

  2. Python 继承、派生、组合、接口、抽象类

    继承是一种是的关系,和组合对比,组合是一种有的关系,这两者都是解决代用重用问题的 继承 注意:继承不是遗传,在显示角度中,是通过对象抽象成类,再把这些类抽象成一个,就是父类.是自下而上的过程,在程序中 ...

  3. python面向对象--包装标准类型及组合方式授权

    # 实现授权是包装的一个特性.包装一个类型通常是对已存在的类型进行一些自定义定制, # 这种做法可以新建,修改,或删除原有产品的某些功能,而其他的保持不变. # 授权的过程,其实也就是所有的更新功能都 ...

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

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

  5. python 面向对象学习

    ------Python面向对象初 下面写一个类的简单实用,以便方便理解类 #python 3.5环境,解释器在linux需要改变 #阅读手册查询readme文件 #作者:S12-陈金彭 class ...

  6. Python面向对象-day07

    写在前面 上课第七天,打卡: 时间的高效利用: 前言: 今天egon老师补充了下 is 和 == 的区别,整理如下:Python中变量的属性以及判断方法 一.面向过程和面向对象 - 1.面向过程 核心 ...

  7. python面向对象-三大特性

    python面向对象编程三大特性 小结:前面我们说完了类和对象的关系,相信对类和对象的理解更加透彻..让我们一起去研究面向对象的三大特性吧.... 继承 1.什么继承? 在程序中继承就是事物之间的所属 ...

  8. Python面向对象三要素-继承(Inheritance)

    Python面向对象三要素-继承(Inheritance) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.继承概述 1>.基本概念 前面我们学习了Python的面向对象三 ...

  9. python—面向对象设计

    一:三大编程范式 1.面向过程编程 2.函数式编程 3.面向对象编程 (类:把一类事物的相同的特征和动作整合到一起就是类,类是一个抽象的概念) (对象:就是基于类而创建的一个具体的事物 [具体存在的] ...

  10. Python面向对象05 /私有成员、类方法、静态方法、属性、isinstance/issubclass

    Python面向对象05 /私有成员.类方法.静态方法.属性.isinstance/issubclass 目录 Python面向对象05 /私有成员.类方法.静态方法.属性.isinstance/is ...

随机推荐

  1. #region在多种编程语言及IDE中进行代码折叠,包括python msvc++ c#等

    vs/rider中折叠C#代码 在写C#的时候,在visual studio中可以使用#region和#endregion来进行代码折叠,那么在pycharm中是否可以呢? //这里有很多的代码... ...

  2. svn忽略某个目录后update出现fetching

    忽略某个子目录 在svn udpate一个大目录时忽略特定的子目录,主要是子目录下内容已经单独拉取过,并且这个大目录对于程序来说,可以是只读的. 操作方法:选中要忽略的目录,右键 svn - Unve ...

  3. TienChin-课程管理-课程搜索

    后端 新建 CourseVO.java: /** * CourseVO类是一个课程的值对象,用于存储课程的相关信息. * 它包含了课程的名称.类型.适用对象.最低价格和最高价格等属性. */ publ ...

  4. PaddleNLP通用信息抽取技术UIE【一】产业应用实例:信息抽取{实体关系抽取、中文分词、精准实体标。情感分析等}、文本纠错、问答系统、闲聊机器人、定制训练

    相关文章: 1.快递单中抽取关键信息[一]----基于BiGRU+CR+预训练的词向量优化 2.快递单信息抽取[二]基于ERNIE1.0至ErnieGram + CRF预训练模型 3.快递单信息抽取[ ...

  5. 【1】paddle飞桨框架高层API使用讲解

    1.高层API简介 飞桨框架2.0全新推出高层API,是对飞桨API的进一步封装与升级,提供了更加简洁易用的API,进一步提升了飞桨的易学易用性,并增强飞桨的功能. 飞桨高层API由五个模块组成:数据 ...

  6. Linux进程间通信 [补档-2023-07-27]

    Linux进程间通信 10-1 简介 ​ 在Linux下,进程之间相互独立,每个进程都有自己不同的用户地址空间.任何一个进程的全局变量在另 一个进程中都看不到,所以进程和进程之间不能相互访问.如果非要 ...

  7. SSM项目创建步骤(随手记)

    一.mybatis项目创建 1:创建maven项目 2:导入pom坐标 3:resources下创建SqlMapConfig.xml配置文件(主配置文件,配置数据库信息,映射配置文件等) 4:创建包及 ...

  8. 在K8S中,Pod亲和性概念是什么?

    在Kubernetes(简称K8S)中,Pod亲和性和反亲和性(Affinity and Anti-Affinity)是集群调度策略的重要组成部分,它们用于控制Pod如何与节点或其他Pod相对应地放置 ...

  9. ESXi6.5导入虚拟机提示缺少所需的磁盘镜像

    环境 esxi6.7 错误提示 解决方案 原因:这是因为导出虚拟机的时候,没有把"CD/DVD驱动器"删掉,在导入的时候,找不到这个磁盘映像. 编辑.ovf文件,找到ovf:hre ...

  10. 如何快速获取AWR中涉及到的表

    最近遇到一个很少见的需求,是关于应用测试方面的. 具体来说,这个应用的测试需求要基于一个固定的时间点数据,而且只能测试一轮,再测试就需要还原到测试前状态. 因为我们使用的存储是分层的(热数据在Flas ...