继承

在面向对象的程序设计中,当我们定义一个class时候,可以从现有的class继承,新的class成为子类,被继承的class称为基类,父类或超类。

比如,编写一个名为Animal的class:

 class Animal(object):
def run(self):
print('动物可以跑')

接着编写两个从Animal继承的类:Dog和Cat:

 class Dog(Animal):
pass class Cat(Animal):
pass

那么,对于Dog、Cat来说,Animal就是父类,对于Animal来说,Dog、Cat就是子类。(其实Animal是object的子类……继承还可以一级一级的继承下来,形成继承树,就好比爸爸继承于爷爷,儿子继承于爸爸的关系。python中,任何类最终都可以追溯到根类object,面向对象中的上帝啊)

尝试运行:

>>> dog = Dog()
>>> cat = Cat()
>>> dog.run()
动物可以跑
>>> cat.run()
动物可以跑

上述结果告诉我们,子类什么事都没干的情况,就具有了父类的功能。这就是继承的好处。

再尝试做如下修改:

 class Dog(Animal):
def run(self):
print('狗在跑')
def eat(self):
print('狗吃香香') class Cat(Animal):
def run(self):
print('猫在跑')
def eat(self):
print('猫吃鱼')

运行结果:

>>> dog = Dog()
>>> cat = Cat()
>>> dog.run()
狗在跑
>>> cat.run()
猫在跑
>>> dog.eat()
狗吃香香

上述例子,也展示了继承的第二个好处——可以对子类增加一些父类中没有的方法eat():继承可以把父类的所有功能直接拿过来,这样就不必从零做起,子类既可以新增特有的方法,同时也可以覆盖父类的方法。

同时,我们改写了run()方法。当子类和父类存在性相同的run()方法时,我们说子类的run()方法覆盖了父类的run()方法,运行子类的实例代码时,调用的是子类的run()方法,这就是继承的另外一个特点——多态。

多态

当我们定义一个class的时候,我们实际上就是定义了一个数据类型。这些自定义的数据类型和python内置的数据类型,本质上没有什么区别:

>>> a = list()
>>> b = Animal()
>>> c = Dog()
>>> isinstance(a,list)
True
>>> isinstance(b,Animal)
True
>>> isinstance(c,Dog)
True
>>> isinstance(c,Animal)
True

isinstance()函数可以判断变量是否是指定的类型。最后一条记录告诉我们,c不仅仅是Dog数据类型,还是Animal数据类型。仔细想想,Dog从Animal继承而来,c是Dog没错,当然同时也是Animal喽,换句自然界的说法:Dog本来就是Animal的一种。

反过来呢:

>>> isinstance(b,Dog)
False

可知:Dog可以看做是Animal,但是Animal却不能看成Dog。

多态有什么好处呢?实际上,任何依赖父类作为参数的函数或者方法都可以不加修改的正常运行下去。举例:

>>> def runAnimal(animal):
... animal.run()
...
>>> runAnimal(Dog())
狗在跑
>>> runAnimal(Cat())
猫在跑

我们发现,任何Animal的子类,都可以在runAnimal()上运行,而不需要我们去修改方法内容。

总结一下多态:

对于一个变量,我们只需要知道他是Animal类型,并不需要知道他的子类,就可以调用run()方法,而具体调用的run()方法是作用在Animal、Dog还是Cat对象上,由运行时该类型的确切类型决定——即调用方只管调用,不需要关注细节,而当我们新增一种Animal的子类时,只需要确保run()方法编写正确即可,不用管是如何调用的。这就是‘开闭’原则:

对扩展开放:允许新增Animal的子类

对修改封闭:不需要修改依赖Animal类型的runAnimal()函数。

扩展:

对于静态语言例如java来说,如果规定了传入的参数是Animal类型,那么我们必须要保证传入的对象是Animal类型或者他的子类,否则会出错。

然而对于python这样的动态语言来说,则不一定需要传入Animal的类型,我们只需保证传入的对象具有一个run()函数即可:

>>> class T(object):
... def run(self):
... print('T run ^')
...
>>> runAnimal(T())
T run ^

这就是动态语言的‘鸭子类型’,它并不要求严格的继承体系,一个对象只要‘看起来像鸭子,走起路来像鸭子’,那他就可以被看做是鸭子。

Python面向对象-继承和多态特性的更多相关文章

  1. Python面向对象 -- 继承和多态、获取对象信息、实例属性和类属性

    继承和多态 继承的好处: 1,子类可以使用父类的全部功能 2,多态:当子类和父类都存在相同的方法时,子类的方法会覆盖父类的方法,即调用时会调用子类的方法.这就是继承的另一个好处:多态. 多态: 调用方 ...

  2. Python面向对象三要素-多态

    Python面向对象3要素-多态 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.  一.多态概述 OCP原则:多用“继承”,少修改. 继承的用途:在子类上实现对基类的增强,实现多态. ...

  3. python基础——继承和多态

    python基础——继承和多态 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类 ...

  4. Python面向对象之:三大特性:继承,封装,多态以及类的约束

    前言: python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情 ...

  5. Python之路-面向对象&继承和多态&类属性和实例属性&类方法和静态方法

    一.面向对象 编程方式 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强…” 什么是面 ...

  6. Python学习(七)面向对象 ——继承和多态

    Python 类的继承和多态 Python 类的继承 在OOP(Object Oriented Programming)程序设计中,当我们定义一个class的时候,可以从某个现有的class 继承,新 ...

  7. Python面向对象继承案例

    面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 继承 实现代码的重用,相同的代码不需要重复的编写 多态 不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活 ...

  8. python面向对象(封装、多态、反射)

    目录 面向对象之封装 @property 面向对象之多态 面向对象之反射 面向对象之封装 含义 将类中的某些名字按照特殊的书写方式"隐藏"起来,不让外界直接调用,目的是为了不然外界 ...

  9. python中继承和多态

    继承和多态 继承 引入继承 我们有这样一个需求 模仿英雄联盟定义两个英雄类 1.英雄要有昵称.攻击力.生命值属性 2.实例化出两个英雄对象 3.英雄之间可以互殴,被殴打的一方掉血,血量小于0则判断为死 ...

随机推荐

  1. Single-Shot Object Detection with Enriched Semantics

    整合一下能够查到的资料,然后结合自己的理解,算是对这篇文章的一个小小的总结吧.这是CVPR2018的一篇关于小目标检测的文章,出发点是作者认为小目标的检测信息随着层数的增加而不断地丢失了,所以想利用语 ...

  2. STDN: Scale-Transferrable Object Detection论文总结

    概述 STDN是收录于CVPR 2018的一篇目标检测论文,提出STDN网络用于提升多尺度目标的检测效果.要点包括:(1)使用DenseNet-169作为基础网络提取特征:(2)提出Scale-tra ...

  3. 前端开发单位em

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Java正则表达式Pattern和Matcher类

    转载自--小鱼儿是坏蛋(原文链接) 概述 Pattern类的作用在于编译正则表达式后创建一个匹配模式.    Matcher类使用Pattern实例提供的模式信息对正则表达式进行匹配 Pattern类 ...

  5. 【Android - 自定义View】之自定义View浅析

    1.概述 Android自定义View / ViewGroup的步骤大致如下: 1) 自定义属性: 2) 选择和设置构造方法: 3) 重写onMeasure()方法: 4) 重写onDraw()方法: ...

  6. linux任务计划cron、chkconfig工具、systemd管理服务、unit和target介绍

    第8周第1次课(5月14日) 课程内容: 10.23 linux任务计划cron10.24 chkconfig工具10.25 systemd管理服务10.26 unit介绍10.27 target介绍 ...

  7. 查看/设置JVM使用的垃圾收集器

    一.设置垃圾收集器的参数 -XX:+UseSerialGC,虚拟机在Client模式下的默认值,Serial+Serial Old -XX:+UseParNewGC,ParNew+Serial Old ...

  8. MyBatis的配置与使用(增,删,改,查)

    ---恢复内容开始--- Mybatis入门介绍 一.MyBatis介绍 什么是MyBtis? MyBatis 是一个简化和实现了 Java 数据持久化层(persistence layer)的开源框 ...

  9. 【玩转MLS系列】基础教程

    1.申请华为机器学习服务MLS标准版服务: 1.如果还未注册华为云,请先进入华为云官网https://www.huaweicloud.com/进行注册:如果已注册,请登录,转第2步. 2.在华为云官网 ...

  10. 深入理解Android异步消息处理机制

    一.概述 Android 中的异步消息处理主要分为四个部分组成,Message.Hndler.MessageQueue 和 Looper.其关系如下图所示: 1. Message 是线程之间传递的消息 ...