以Animal类为例,假设要实现以下4种动物:

Dog(狗)、Bat(蝙蝠)、Parrot(鹦鹉)和Ostrich(鸵鸟)

如果按照哺乳类和鸟类来区分的话,可以这样设计:

Animal:

  |--Mammal

    |--Dog

    |--Bat

  |--Bird

    |--Parrot

    |--Ostrich

但是,如果按照能跑和能飞来归类的话,又可以这么设计:

Animal:

  |--Runnable

    |--Dog

    |--Ostrich

  |--Flyable

    |--Parrot

    |--Bat

如果再以宠物类和非宠物类等等规则来划分的话,类的数量会非常非常多的。

python允许我们使用多重继承来设计。

首先,我们仍然将哺乳类和鸟类作为类层次的最主要部分来设计:

>>> class Animal(object):
... pass
...
>>> class Mammal(Animal):
... pass
...
>>> class Bird(Animal):
... pass
...
>>> class Dog(Mammal):
... pass
...
>>> class Bat(Mammal):
... pass
...
>>> class Parrot(Bird):
... pass
...
>>> class Ostrich(Bird):
... pass
...

我们还可以给动物再加上Runnable和Flyable功能。只需要定义好Runnable和Flyable的类,然后对需要Runnable和Flyable功能的动物,直接继承相应的类即可,实现一个子类同时获得多个父类的所有功能:

>>> class Runnable(object):
... pass
...
>>> class Flyable(object):
... pass
...
>>> class Runnable(object):
... def run(self):
... print('能走')
...
>>> class Flyable(object):
... def fly(self):
... print('飞喽')
...
>>> class Dog(Mammal,Runnable):
... pass
...
>>> class Bat(Mammal,Flyable):
... pass
...
>>> d = Dog()
>>> d.run()
能走

MixIN

我们在设计类的时候,建议主线单一继承,例如Ostrich继承自Bird,但是当需要添加额外的功能时,可以通让Ostrich同时继承Bird和Runnable,这样Ostrich就会同时获得Bird和Runnable的所有属性和方法。这种设计通常叫做MixIN。

例如,我们还可以定义肉食动物Carnivorous和植食动物Herbivores,让Dog同时拥有好多的MixIN:

class Dog(Mammal, RunnableMixIn, CarnivorousMixIn):
pass

最后,MixIN告诉我们要优先考虑通过多继承来组合多个功能,而不是设计多层次的复杂的继承关系。

Python面向对象-多重继承之MixIN的更多相关文章

  1. python面向对象高级:Mixin多重继承

    继上一篇学习笔记:python面向对象的继承与多态,本篇就Mixin扩展类的方法写下学习笔记 Mixin Mixin编程是一种开发模式,是一种将多个类中的功能单元的进行组合的利用的方式,这听起来就像是 ...

  2. Python 面向对象 —— 多重继承

    多重继承(一个子类同时继承多个父类),容易造成混乱,即如果两个父类又相同的方法名和变量名时,无法确定继承哪一个. 正因如此,Java 等语言中并不支持多重继承(Java 是单继承多接口).Python ...

  3. Python学习笔记之Python的多重继承和MixIn

    多重继承 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能. 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗: Bat - 蝙蝠: Parr ...

  4. Python面向对象——多重继承大揭秘

    1如果如图所示使用多重继承,我们将看到什么 2我们看到了基类被执行了两次Baseclass 3代码验证吧 class BaseClass: num_base_calls = 0 def call_me ...

  5. Python面向对象——多重继承

    1本文的作用 一个从多个父类继承过来的子类,可以访问所有父类的功能. 2图文介绍 3代码验证 class Contact: all_contacts = [] def __init__(self, n ...

  6. Python面向对象 -- slots, @property、多重继承MixIn、定制类(str, iter, getitem, getattr, call, callable函数,可调用对象)、元类(type, metaclass)

    面向对象设计中最基础的3个概念:数据封装.继承和多态 动态给class增加功能 正常情况下,当定义了一个class,然后创建了一个class的实例后,可以在程序运行的过程中给该实例绑定任何属性和方法, ...

  7. python基础——多重继承

    python基础——多重继承 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能. 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗: Bat ...

  8. Python面向对象:杂七杂八的知识点

    为什么有这篇"杂项"文章 实在是因为python中对象方面的内容太多.太乱.太杂,在写相关文章时比我所学过的几种语言都更让人"糟心",很多内容似独立内容.又似相 ...

  9. Python面试题之Python面向对象编程汇总

    面向对象的设计思想是从自然界中来的,因为在自然界中,类(Class)和实例(Instance)的概念是很自然的.Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念, ...

随机推荐

  1. 新闻实时分析系统-HBase分布式集群部署与设计

    HBase是一个高可靠.高性能.面向列.可伸缩的分布式存储系统,利用Hbase技术可在廉价PC Server上搭建 大规模结构化存储集群. HBase 是Google Bigtable 的开源实现,与 ...

  2. 【NHOI2018】字符串变换

    [题目描述] 给你一个全部由大小写字母组成的字符串,你每次可以将一个小写字母变换成对应的大写字母,或把一个大写字母变换成对应的小写字母.请问:至少要进行多少次变换才可以使整个字符串全部由大写字母或全部 ...

  3. Python函数的默认参数的设计【原创】

    在Python教程里,针对默认参数,给了一个“重要警告”的例子: def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print( ...

  4. 探究 C# 中的 char 、 string(一)

    目录 探究 C# 中的 char . string(一) 1. System.Char 字符 2. 字符处理 3. 全球化 4. System.String 字符串 4.1 字符串搜索 4.2 字符串 ...

  5. Spring项目中优雅的异常处理

    前言 如今的Java Web项目多是以 MVC 模式构建的,通常我们都是将 Service 层的异常统一的抛出,包括自定义异常和一些意外出现的异常,以便进行事务回滚,而 Service 的调用者 Co ...

  6. 如何运用DDD - 实体

    目录 如何运用DDD - 实体 概述 何为实体 似曾相识 你确定它真的需要ID吗 运用实体 结合值对象 为实体赋予它的行为 尝试转移一部分行为给值对象 愿景是美好的 现实是残酷的 总结 如何运用DDD ...

  7. HTML标签-->HTML5新增

    HTML的Form新增属性 <form method="post" name="myForm"> <p> 邮箱:<input ty ...

  8. Docker 遇到的一些错误

    1.version Base not defined in file libdevmapper.so.1.02 在 Centos 6.5 上安装docker-io之后,使用/etc/init.d/do ...

  9. df命令、du命令、磁盘分区 使用介绍

    第4周第1次课(4月9日) 课程内容:4.1 df命令4.2 du命令4.3/4.4 磁盘分区 4.1 df命令 汇报磁盘空间使用情况,linux磁盘挂载点是无法直接访问的. df 和 df -h区别 ...

  10. Spring Cloud Gateway - 路由法则

    1. After Route Predicate Factory 输入一个参数:时间,匹配该时间之后的请求,示例配置: spring: cloud: gateway: routes: - id: af ...