继承

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

    关于Dart的几点重要说明 在Dart中所有变量都是一个对象,所有对象都是一个类的实例.每个数字,方法,甚至是Null都是对象.所有的对吸纳更都是集成自Object这个类.(这个说法其实是很像Java ...

  2. 宋宝华:关于ARM Linux原子操作的实现

    本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) 竞态无所不在 首先我们要理解竞态(ra ...

  3. es6 filter方法应用

    let arr =[ {title:'aaaa',read:100,hot:true}, {title:'bbbb',read:50,hot:false}, {title:'ccc',read:100 ...

  4. DNS资源记录的七类

    在Microsoft产品系列中,ADDS是一个很出色的设计平台,说到AD,那么我们就不得不提起他的合作伙伴--DNS,相信大家都知道,DNS在AD中的重要地位,就如男人和女人一样,要想有所作为,他们2 ...

  5. P2415 集合求和(一道洛谷好题鸭)(虽然可以水过,但有必研究DP)

    此题坑点: 结果必须要用long long存,int存不下 如果想要像cout<<sum*pow(2,num-1)这样在输出时计算会错:long long在计算过程被隐式转换成了doubl ...

  6. Django总结目录

    Django总结目录 1. django框架简介及自定义简易版框架 2. 路由层 3. 视图层 4. 模板层 5. 模型层 5.1 基本操作 5.2 多表操作 5.3 进阶相关 6. 组件 6.1 a ...

  7. python logging模块小记

    1.简单的将日志打印到屏幕 import logging logging.debug('This is debug message') logging.info('This is info messa ...

  8. Python中的Base64编码的加密与解密

    Base64 可以干些啥? Base64编码的作用: 由于某些系统中只能使用ASCII字符.Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法. 图片(and种子)base64 ...

  9. “Unknown class XXViewController in Interface Builder file.”问题处理

    在静态库中写了一个XXViewController类,然后在主工程的xib中,将xib的类指定为XXViewController,程序运行时,报了如下错误: “Unknown class XXView ...

  10. goal

    线段树进阶,主席树,莫队,相似kmp,悬线,单调栈,单调队列,ac自动机,后缀数组,后缀自动机 图论:最短路,差分约束,二分图,网络流,连通分量 不学图论了我太难了   三分找,单调增+max+单调减 ...