*继承

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

比如,我们已经编写了一个名为Animal的class,有一个run()方法可以直接打印:

class Animal(object):

  1. def run(self):
  2. print('Animal is running...')
  3. 当我们需要编写DogCat类时,就可以直接从Animal类继承:
  1. class Dog(Animal):
  2. pass
  3. class Cat(Animal):
  4. pass

对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类。CatDog类似。

继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Animial实现了run()方法,因此,DogCat作为它的子类,什么事也没干,就自动拥有了run()方法

如下所示

  1. dog = Dog()
  2. dog.run()
  3. cat = Cat()
  4. cat.run()
  5.  
  6. 运行结果如下:
  1. Animal is running...
  2. Animal is running...
    当然,也可以对子类增加一些方法,比如对Cat
  1. class Cat(Animal):
  2. def run(self):
  3. print('Dog is running...')
  4. def eat(self):
  5. print('Eating meat...')

  6. 需要注意的是:当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态。

继承还可以一级一级地继承下来,就好比从爷爷到爸爸、再到儿子这样的关系。而任何类,最终都可以追溯到根类object,这些继承关系看上去就像一颗倒着的树。比如如下的继承树:

  1. ┌───────────────┐
  2. object
  3. └───────────────┘

  4. ┌────────────┴────────────┐


  5. ┌─────────────┐ ┌─────────────┐
  6. Animal Plant
  7. └─────────────┘ └─────────────┘

  8. ┌─────┴──────┐ ┌─────┴──────┐


  9. ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
  10. Dog Cat Tree Flower
  11. └─────────┘ └─────────┘ └─────────┘ └─────────┘
  12.  
  13.  
  14. *多态
  1. 要理解什么是多态,我们首先要对数据类型再作一点说明。当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如strlistdict没什么两样:
    比如:
  1. a = list() # a是list类型
  2. b = Animal() # b是Animal类型
  3. c = Dog() # c是Dog类型

判断一个变量是否是某个类型可以用isinstance()判断:

  1. >>> isinstance(a, list)
  2. True
  3. >>> isinstance(b, Animal)
  4. True
  5. >>> isinstance(c, Dog)
  6. True

看来abc确实对应着listAnimalDog这3种类型。

但是等等,试试:

  1. >>> isinstance(c, Animal)
  2. True

看来c不仅仅是Dogc还是Animal

不过仔细想想,这是有道理的,因为Dog是从Animal继承下来的,当我们创建了一个Dog的实例c时,我们认为c的数据类型是Dog没错,但c同时也是Animal也没错,Dog本来就是Animal的一种!

所以,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行:

  1. >>> b = Animal()
  2. >>> isinstance(b, Dog)
  3. False

Dog可以看成Animal,但Animal不可以看成Dog

要理解多态的好处,我们还需要再编写一个函数,这个函数接受一个Animal类型的变量:

  1. def run_twice(animal):
  2. animal.run()
  3. animal.run()

当我们传入Animal的实例时,run_twice()就打印出:

  1. >>> run_twice(Animal())
  2. Animal is running...
  3. Animal is running...

当我们传入Dog的实例时,run_twice()就打印出:

  1. >>> run_twice(Dog())
  2. Dog is running...
  3. Dog is running...

当我们传入Cat的实例时,run_twice()就打印出:

  1. >>> run_twice(Cat())
  2. Cat is running...
  3. Cat is running...

看上去没啥意思,但是仔细想想,现在,如果我们再定义一个Tortoise类型,也从Animal派生:

  1. class Tortoise(Animal):
  2. def run(self):
  3. print('Tortoise is running slowly...')

当我们调用run_twice()时,传入Tortoise的实例:

  1. >>> run_twice(Tortoise())
  2. Tortoise is running slowly...
  3. Tortoise is running slowly...

你会发现,新增一个Animal的子类,不必对run_twice()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。

多态的好处就是,当我们需要传入DogCatTortoise……时,我们只需要接收Animal类型就可以了,因为DogCatTortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思

*动态语言与静态语言的区别

静态语言

对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。

动态语言

对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了。

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

就是说只要有一个方面相似,就能继承。

  1. 小结:
    继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
  1.  

python3中的继承和多态的更多相关文章

  1. Python面向对象中的继承、多态和封装

    Python面向对象中的继承.多态和封装 一.面向对象的三大特性 封装:把很多数据封装到⼀个对象中,把固定功能的代码封装到⼀个代码块, 函数,对象, 打包成模块. 这都属于封装思想. 继承:⼦类可以⾃ ...

  2. C中的继承和多态

    昨天同学面试被问到这个问题,很有水平,以前都没有遇到过这个问题,一时自己也不知道怎么回答. 网上学习了一下,记录以备后用! C/C++ Internals : 里面的问题都写的不错,可以读读! Ref ...

  3. java中的继承 和多态。

    package com.aaa.zxf.ajax.test; /** *一. java 中的继承和多态. * * 继承的特性? * 1.实现继承的方式 * A 如何建立继承关系(一个类继承于 另一个类 ...

  4. Python 中的继承、多态和封装

    涉及问题: Python 中如何实现多继承,会有什么问题? Python 中的多态与静态方法有什么区别? 答案要点如下: Python 中的继承,就是在定义类时,在括号中声明父类,简单示例如下: cl ...

  5. Objective-C中的继承和多态

    面向对象编程之所以成为主流的编程思想和他的继承和多态是分不开的,只要是面向对象语言都支持继承和多态,当然不同的OOP语言之间都有其特点.OC中和Java类似,不支持多重继承,但OOP语言C++就支持多 ...

  6. 2017.10.10 java中的继承与多态(重载与重写的区别)

    1. 类的继承 继承是面向对象编程技术的主要特征之一,也是实现软件复用的重要手段,使用继承特性子类(subclass) 可以继承父类(superclass)中private方法和属性,继承的目的是使程 ...

  7. Java中的继承和多态

    1.  什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法,使得子类具有父类相同的行为. 特点:在继承关系中,父类更通用.子类更具体.父类具有更 ...

  8. 简谈java 中的 继承和多态

    继承(extends) : 1:object 是所有类的父(基)类. 2:子类继承父类所有的内容除了(private修饰的和构造方法). 3:子类在手动创建构造方法时,必须调用父类构造方法. 4:在J ...

  9. 【Java学习笔记之十六】浅谈Java中的继承与多态

    1.  什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法,使得子类具有父类相同的行为. 特点:在继承关系中,父类更通用.子类更具体.父类具有更 ...

随机推荐

  1. 【转载】你未必知道的49个CSS知识点

    原文链接: https://juejin.im/post/5d3eca78e51d4561cb5dde12 虽然大多数我都会,嘻嘻.不过案例太生动了,值得收藏.

  2. ECShop二次开发指南-文件结构(二)

      ecshop文件架构说明 注意:因各版权不一,大概参考/* ECShop 2.5.1 的结构图及各文件相应功能介绍 ECShop2.5.1_Beta upload 的目录 ┣ activity.p ...

  3. Nginx 究竟如何处理事件?

    在了解了网络事件以及事件分发收集器以后,让我们来了解 Nginx 是怎么样处理事件的? Nginx 事件循环 当 Nginx 刚刚启动时,在等待事件部分,也就是打开了 80 或 443 端口,这个时候 ...

  4. web三要素

    1.带动web的三驾马车 html5,css,javascript(js)就是带动web的三架马车,html是web的结构,css是web的样式,而js则是web的行为(即与用户的交互) 如果把htm ...

  5. 【转】Matlab多项式拟合

    转:https://blog.csdn.net/hwecc/article/details/80308397 例: x = [0.33, 1.12, 1.41, 1.71, 2.19] y = [0. ...

  6. rsync 服务介绍及相关实验

    一.rsync 简介 rsync 是类 unix 系统下的数据镜像备份工具.一款支持快速完全备份和增量备份的工具,支持本 地复制,远程同步等,类似于 scp 命令:rsync 命令在同步文件之前要先登 ...

  7. 字符串String类常见算法题

    1.将一个字符串进行反转.将字符串中指定部分进行反转. public class StringDemo { //方式一:转换为char[] public String reverse(String s ...

  8. php5升php7代码修改整理

    1. 为什么升级至php7 a.安全需要 过早以至于不维护的php版本难免会有未修补的漏洞,安全性要求较高的行业是要及时升级的. b.性能提升(开启opcache hugepage) 据说性能提升一倍 ...

  9. 【C_Language】---C文件学习

    ---恢复内容开始--- 又看了一遍文件的知识点了,断断续续已经看了2-3遍,也就这次花了点时间做了一下总结,以后我想都不会再去翻书了,哈哈. 1. 基于缓冲区的文件操作2. 打开关闭文件3. 单个字 ...

  10. 求树上任意一点所能到达的最远距离 - 树上dp

    A school bought the first computer some time ago(so this computer's id is 1). During the recent year ...