一、继承

  原则:大部分使用继承的场合都可以用组合取代或者简化,而多重继承则需要不惜一切的避免。

  1. 什么是继承

  继承:用于指明一个类的大部分或者全部功能都是从一个父类获得的。此时,父类的实例的所有动作可能都会工作在子类的实例上,这样可以把通用的功能放在父类里边,然后给子类设定一些特别的功能。

  父类和子类的三种交互方式:

  ① 子类上的动作完全等同于父类上的动作

  ② 子类上的动作完全覆盖了父类上的动作

  ③ 子类上的动作部分替换了父类上的动作

  2. 隐式继承

  如果在父类中定义了一个函数,而在子类中没有定义,则会发生隐式的继承。也就是说,子类的实例可以调用仅在父类中定义过而在子类中没有定义过的函数。

 class Parent(object):

     def implicit(self):
print("PARENT IMPLICIT()") class Child(Parent):
pass dad = Parent()
son = Child() dad.implicit()
son.implicit()

  输出为

PARENT IMPLICIT()
PARENT IMPLICIT()

  3. 显式覆盖

  如果想要在子类里的函数有不同的功能,则必须使用显式覆盖,这在子类中定义一个同名函数就可以了,如

 class Parent(object):

     def override(self):
print("PARENT OVERRIDE()") class Child(Parent): def override(self):
print("CHILD OVERRIDE()") dad = Parent()
son = Child() dad.override()
son.override()

  输出为

PARENT OVERRIDE()
CHILD OVERRIDE()

  4. 在运行前或运行后替换

  替换是覆盖的一种特例。它允许我们在父类定义的内容运行之前或之后再去修改子类的行为。

  其方法为,首先像上例一样覆盖父类的函数,然后用super()调用该函数在父类里的版本。

 class Parent(object):

     def altered(self):
print("PARENT altered()") class Child(Parent): def altered(self):
print("CHILD, BEFORE PARENT altered()") # 显式覆盖
super(Child,self).altered() # 用super(Child,self)调用父类的同名函数
print("CHILD, AFTER PARENT altered()") # 仍为显式覆盖的部分 dad = Parent()
son = Child() dad.altered()
son.altered()

  输出为

PARENT altered()
CHILD, BEFORE PARENT altered()
PARENT altered()
CHILD, AFTER PARENT altered()

  可见,一方面,我们可以显式覆盖,重写子类同名函数的内容和功能;另一方面,可以用super(Child,self)函数在中间调用父类的同名函数,而它并不影响前后的覆盖内容。

  因此,我们可以在子类函数运行前或运行后替换,这取决于super()的位置。

  5. 三种方式的组合使用

 class Parent(object):

     def implict(self):
print("PARENT implict()") def override(self):
print("PARENT override()") def altered(self):
print("PARENT altered()") class Child(Parent): def override(self):
print("CHILD override()") def altered(self):
print("CHILD, BEFORE PARENT altered()")
super(Child, self).altered()
print("CHILD, AFTER PARENT altered()") dad = Parent()
son = Child() dad.implict()
son.implict() dad.override()
son.override() dad.altered()
son.altered()

  输出为

PARENT implict()
PARENT implict()
PARENT override()
CHILD override()
PARENT altered()
CHILD, BEFORE PARENT altered()
PARENT altered()
CHILD, AFTER PARENT altered()

  6. super()函数

  ① 多重继承

  指定义的类继承了一个或多个类,例如

class SuperFun(Child, BadStuff):
pass

  此时,一旦在SuperFun的实例上调用任何隐式动作,Python就必须返回到Child和BadStuff的类层次结构中去查找可能的函数,而且必须用固定的顺序去查找。

  为此,Python使用了“Method Resolution Oder(方法解析顺序),MRO”+C3算法,并提供super()函数,用于实现这些功能。这样,就可以方便的使用super()来查询各父类的函数了。

  ② super()与__init__的搭配使用

  super()最常见的用法是,在父类的__init__函数中使用。它使得我们可以先在子类中实现一些功能,然后再让父类初始化,例如

 class Child(Parent):

     def __init__(self, stuff):
self.stuff = stuff
super(Child, self).__init__()

  二、组合

  组合能够实现和继承几乎完全相同的功能,但它采用的方法并非是隐式继承,而是通过调用模块里的函数来实现。

 class Other(object):

     def implicit(self):
print("OTHER implicit()") def override(self):
print("OTHER override()") def altered(self):
print("OTHER altered()") class Child(object): def __init__(self):
self.other = Other() def implicit(self):
self.other.implicit() def override(self):
print("CHILD override()") def altered(self):
print("CHILD, BEFORE OTHER altered()")
self.other.altered()
print("CHILD, AFTER OTHER altered()") son = Child() son.implicit()
son.override()
son.altered()

  输出为

OTHER implicit()
CHILD override()
CHILD, BEFORE OTHER altered()
OTHER altered()
CHILD, AFTER OTHER altered()

  可见,这里并不是为Child指定了一个父类,而是将父类的功能打包为一个模块(实质也是一个类),然后直接调用模块里面的函数,这也能够完成和继承相同的功能。

  三、继承和组合的应用场合

  继承和组合事实上都是为了解决代码的复用问题。前者通过创建一种让我们在子类里隐含父类的功能的机制来解决这个问题,后者通过模块/类中的函数调用达到了相同的目的。关于二者的选择,大体上有3个指导原则:

  1. 避免多重继承。多重继承复杂且不可靠,如果要使用,需要钻研一下类层次结构及其来龙去脉。

  2. 如果有一些代码会在不同位置和场合应用到,就用组合将它们做成模块。

  3. 只有在代码的可复用部分之间有清楚的关联,可以通过一个单独的共性连接起来的时候,才使用继承。

【巩固练习】代码风格参考 PEP 8 -- Style Guide for Python Code

【注意】在有的语言如JavaScript中,对象其实是类的副本,这样的语言叫原型(prototype)语言,这种语言中类和对象除了用法以外没多少不同。但在Python中,类则比较像是用来创建对象的模板。

【Python基础】lpthw - Exercise 44 继承与组合的更多相关文章

  1. Python 入门基础20 --面向对象_继承、组合

    今日内容 组合:自定义类的对象作为类的属性 继承:父类与子类.多继承 1.组合 将自定义类的对象作为类的属性 class Teacher: def __init__(self, name): self ...

  2. python基础学习笔记—— 多继承

    本节主要内容: 1.python多继承 2.python经典类的MRO 3.python新式类的MRO.C3算法 4.super是什么鬼? 一.python多继承 在前⾯的学习过程中. 我们已经知道了 ...

  3. python基础学习笔记——单继承

    1.为什么要有类的继承性?(继承性的好处)继承性的好处:①减少了代码的冗余,提供了代码的复用性②提高了程序的扩展性 ③(类与类之间产生了联系)为多态的使用提供了前提2.类继承性的格式:单继承和多继承# ...

  4. python基础学习之类的继承、魔法方法

    什么是继承 即类A可以使用类B的方法,即B是A的父类,A是B的子类,AB之间是继承关系 class Father():  # 父类 def __init__(self,name,age): self. ...

  5. python基础(17)继承类和面向对象初识

    1.继承类 class Lm: money = 1000000 house = 5 def driver(self): print('会开车') class Mcb(Lm): def about_me ...

  6. python基础——继承与派生、组合

    python基础--继承与派生 1 什么是继承: 继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类成为基类或超累,新建的类成为派生类或子类 1.1 继承分为:单 ...

  7. python基础----继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法

    一.什么是继承                                                                          继承是一种创建新的类的方式,在pyth ...

  8. python基础之类的继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法

    一.什么是继承 继承是一种创建新的类的方式,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. 派生:子类继承了父类的属性,然后衍生出自己新的属性,如果子类衍生出的新 ...

  9. python基础之继承派生、组合、接口和抽象类

    类的继承与派生 经典类和新式类 在python3中,所有类默认继承object,但凡是继承了object类的子类,以及该子类的子类,都称为新式类(在python3中所有的类都是新式类) 没有继承obj ...

随机推荐

  1. Djangol里面MVT的原理

    MVT Django是一款python的web开发框架与MVC有所不同,属于MVT框架m表示model,负责与数据库交互v 表示view,是核心,负责接收请求.获取数据.返回结果t 表示templat ...

  2. 第十三章 部署Java应用程序

    打包 清单文件被命名为MANIFEST.MF,用于描述归档特征. 清单文件被分为多个节, 第一节被称为主节,作用于整个文件; 其他节则必须起始于Name的条目. 节之间空行分开. jar cfm JA ...

  3. 拍拍熊(APT-C-37),诱导方式、DNS、安卓远控

    诱导方式 1.含有正常APP功能的伪装 2.文件图标伪装 RAR 1.Android DroidJack SpyNote Windows njRAT njRAT[2]又称Bladabindi,通过控制 ...

  4. 提升Tesseract-OCR输出的质量

    图片处理 修改比例(Rescaling) 二值化(Binarisation) 去除噪点(Noise Removal) 旋转/偏移校正(Rotation / Deskewing) 边界(Borders) ...

  5. 【原创】大数据基础之Spark(6)Spark Rdd Sort实现原理

    spark 2.1.1 spark中可以通过RDD.sortBy来对分布式数据进行排序,具体是如何实现的?来看代码: org.apache.spark.rdd.RDD /** * Return thi ...

  6. 【原创】大数据基础之Spark(2)Spark on Yarn:container memory allocation容器内存分配

    spark 2.1.1 最近spark任务(spark on yarn)有一个报错 Diagnostics: Container [pid=5901,containerID=container_154 ...

  7. WIFI的AP/Sta模式简单介绍

    AP模式: Access Point,提供无线接入服务,允许其它无线设备接入,提供数据访问,一般的无线路由/网桥工作在该模式下.AP和AP之间允许相互连接 Sta模式: Station, 类似于无线终 ...

  8. hdu4507 数位dp+推公式

    推公式的能力需要锻炼.. /* dp的时候要存结构体 里面三个元素: cnt,就是满足条件的个数 sum1,就是满足条件的数字和 sum2,满足条件的数字平方和 推导过程:还是用记忆化搜索模板 dp[ ...

  9. 【转】win10哪个版本最好用,推荐win10企业版LTSC

    https://msdn.itellyou.cn/ win10企业版LTSC又被称为win10企业版2019长期服务版本,这个版本小编认为是目前最好用的win10版本,在win10企业版2016长期服 ...

  10. [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入

    https://www.cnblogs.com/masonlu/p/10105135.html