继承

在面向对象的程序设计中,当我们定义一个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. tcpip协议

    几个概念 1.分层(我们使用四层模型更为贴合我们的实际网络) 分层是为什么,其实和公司中职位是一样的,不同职位的人做不同的事情,然后不同职位的人合起来,一起完成了数据传输的事情. 链路层  在这个层面 ...

  2. day 38 高级选择器

    1.高级选择器 一.高级选择器 1-后代选择器 ***** 儿子.孙子.重孙子 1. .father .wu{ color: red; } 选择父类中特定的子类 2. .father p{ #后代中间 ...

  3. Altium Designer 18 画keepout层与将keepout层转换成Mechanical1层的方法

    画keepout的方法 先选中Keepout层:然后 右键->Place->Keepout->然后选择要画圆还是线 Keepout层一般只用来辅助Layout,不能作为PCB的外形结 ...

  4. PyTorch官方教程中文版

    首先呈上链接:http://pytorch123.com/ PyTorch是一个基于Torch的Python开源机器学习库,用于自然语言处理等应用程序.它主要由Facebookd的人工智能小组开发,不 ...

  5. 转:spring aop 拦截业务方法,实现权限控制

    难点:aop类是普通的java类,session是无法注入的,那么在有状态的系统中如何获取用户相关信息呢,session是必经之路啊,获取session就变的很重要.思索很久没有办法,后来在网上看到了 ...

  6. 英飞凌TC297 PSPR与DSPR

    TC297的系统架构图如下,3个核CPU0/1/2有各自的RAM,分为程序RAM和数据RAM,即PSPR和DSPR.PSPR(或者叫做PRAM)主要用于放置静态函数,提高函数执行效率,或放置flash ...

  7. Internet History,Technology,and Security - History Through Supercomputing(Week2)

    时间飞逝,一周又过去了,这周我们来到了Internet History, Technology and Security (Week 2)的学习,从标题就可以看出,这周主要是介绍“互联网”雏形的诞生. ...

  8. luogu P2947 [USACO09MAR]向右看齐Look Up |单调队列

    题目描述 Farmer John's N (1 <= N <= 100,000) cows, conveniently numbered 1..N, are once again stan ...

  9. Go语言学习之路

    我关于Go语言的博客原本发布于我的个人网站:wwww.liwenzhouu.com.但是被某些人抄怕了,没办法只好搬运到博客园. 我的Go语言学习之路 2015年底我因为工作原因接触到了Go语言,那时 ...

  10. [TimLinux] django html如何实现固定表头

    1. 需求 表格很长,这个时候就希望表格头部不动,而只是表格内容行支持滚动功能. 2. 方法 两张表:一张表(THeader)负责头部字段的显示,另一张表(TBody)负责内容行字段的显示. 两张表都 ...