1. 多态

什么是多态

-- 多态,指的是一种事务具有多种形态;

-- python是一种动态语言,默认支持多态,同一个方法 调用 不同的类对象 ,执行的 结果各不相同;

多态实现

-- 继承:不同子类 继承 同一父类;

-- 重写:子类重写 同一个方法,保证执行结果各不相同;

示例

-- 有如下代码:

>>> class Animals():

... def talk(self):

... print("Animal talk")

...

>>>

>>> class People(Animals): # 继承 Animals 类

... def talk(self):

... print('People speak language')

...

>>>

>>> class Cat(Animals): # 继承 Animals 类

... def talk(self):

... print('Cat say miaomiao')

...

>>>

>>> cat = Cat()

>>> peo = People()

>>>

>>> cat.talk() # 调用 talk 方法

Cat say miaomiao

>>> peo.talk() # 调用 talk 方法

People speak language

如上所示:

-- cat 和 peo 两个对象调用同一个 talk() 方法;

-- 最后得到两种不同的结果;

多态的优点:

-- 多态可以增加代码的灵活度;

-- 是调用方法的技巧,不会影响到类的内部设计;

-- 多态可以看做 接口函数的重用,同一种接口方法 通过 接收不同的类 对象,从而实现不同的功能;

多态使用场景:

-- 方法参数接收同一父类的不同子类对象。

2. 鸭子模型

什么是鸭子模型

-- 当看到一只鸟走起来像鸭子,游泳起来也像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子;

-- 鸭子模型和多态一样,都是接受不同的类对象,并调用相同的方法(即:鸭子的 游泳 和 叫 方法);

-- 对于一个鸭子模型来说,我们并 不关心接收的类对象是否真的是鸭子类,只关心这个类是如何被使用的;

-- 注意:如果这些需要被调用的方法不存在,那么将引发一个运行时错误。

示例

-- 有如下代码:

>>> class Duck:

... def quack(self):

... print("duck quack")

...

>>>

>>> class Bird: # Bird 类与 Duck 类无继承关系

... def quack(self):

... print("bird quack")

...

>>>

>>> class Dog: # Dog类与 Duck 类无继承关系

... def quack(self):

... print("dog quack")

...

>>>

>>> def animal_quack(animal): # animal_quack 方法可以调用任何对象的 quack() 方法,不关心对象是谁

... animal.quack()

...

>>>

>>> duck = Duck()

>>> bird = Bird() # bird 实例与 duck 实例无任何关系

>>> dog = Dog() # dog 实例与 duck 实例无任何关系

>>>

>>> for animal in [duck, bird, dog]:

... animal_quack(animal)

...

duck quack

bird quack

dog quack

-- 如上所示:

-- duck、bird、dog 分别来自三个不同的类,而且类之间是 没有继承关系 的;

-- duck、bird、dog 调用 animal_quack 方法,得到三种不同的结果,符合多态的特征;

鸭子模型的优点:

-- 鸭子模型不关关心类对象是什么,不需要类之间具有继承关系;

-- 鸭子模型让代码比多态更加灵活度;

多态使用场景:

-- 鸭子模型中,接收不同的类将会产生不同的行为,而无须明确知道这个类实际上是什么,这是多态的重要应用场景;

-- 实际生产环境中,主要用于 接口开发,即用同一个函数接收不同的类对象,从而实现不同的功能,而且无需关注对象之间的继承关系;

3. 抽象基类

什么是抽象基类

-- 抽象基类,这个词可能听着比较"深奥",其实 抽象 就是 假 的意思,基类 就是 父类,抽象基类 就是 假父类;

-- 具体来说,由 abc.ABCMeta 这个元类实现的类,就是抽象基类;

示例:

-- 如下代码中的 AbstractClass 类继承自 abc.ABCMeta,AbstractClass 就是抽象基类;

class AbstractClass(metaclass=abc.ABCMeta):

pass

抽象基类的作用

-- 判断是否为某个对象的实例

>>> class MyList(object):

... def __init__(self, my_list):

... self.my_list= my_list

... def __len__(self):

... return len(self.my_list)

...

>>>

>>> class NewList(MyList): # NewList 继承自 MyList

... pass

...

>>> ml = MyList(["a", "b", "c"])

>>>

>>> from collections.abc import Sized, Iterable

>>>

>>> print(isinstance(ml, Sized))

True # 返回 True,因为这里会检查实例对象中有没有__len__方法,有即输出True

>>> nl = NewList([1, 2, 3])

>>> print(isinstance(nl, MyList))

True # 返回 True,因为 nl 实例化的类 NewList 同时也是 MyList 的子类

-- 强制要求父类被子类继承,并在子类实现某个方法,否则子类初始化时就会报错;

>>> from abc import ABCMeta,abstractmethod

>>>

>>>

>>> class Source(metaclass=ABCMeta): # 创建抽象基类 Source

... @abstractmethod # 表示装饰的方法必须被子类所实现,否则会报错

... def get(self,key):

... pass

...

>>>

>>> class Mysource(Source): # 子类 Mysource 继承自 抽象基类 Source

... def get(self,key): # 实现 get 方法,这个方法是 抽象基类 Source 强制要求实现的

... pass

...

>>>

>>> class Mysource1(Source): # 子类 Mysource1 没有实现 抽象基类 Source 强制要求实现的 get 方法

... pass

...

>>> test = Source() # test 直接实例化 Source 父类

Traceback (most recent call last): # 此处报错,因为抽象类无法实现实例化

File "", line 1, in

TypeError: Can't instantiate abstract class Source with abstract methods get

>>>

>>> test = Mysource() # 此处实例化 Mysource,未报错

>>>

>>> test = Mysource1()

Traceback (most recent call last): # 报错,继承类必须实现抽象类的方法

File "", line 1, in

TypeError: Can't instantiate abstract class Mysource1 with abstract methods get

抽象基类使用场景

-- 接口强制规定,主要是 强制子类实现某个方法,否则就提示报错;

抽象基类的有点:

-- 处理继承问题方面更加规范、系统;

-- 明确调用之间的相互关系,使得继承层次更加清晰;

抽象基类的缺点:

-- 抽象基类在 python 并非在于用来继承,主要用来理解 python继承 的定义,应该 尽量使用鸭子模型;

-- 如果一定要继承接口的话,比较 推荐多继承,抽象基类容易 设计过度;

python抽象基类的作用_Python:多态、鸭子模型和抽象基类相关推荐

  1. python 类和对象_Python零基础入门学习33:类与面向对象编程:类的继承

    注:本文所有代码均经过Python 3.7实际运行检验,保证其严谨性. 本文字数约1300,阅读时间约为3分钟. Python面向对象编程 类的继承机制 如果一个类A继承自另一个类B,就把继承者类A称 ...

  2. python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景

    装饰器的应用场景附加功能 数据的清理或添加:函数参数类型验证 @require_ints 类似请求前拦截数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改为函数提供额外的数据 moc ...

  3. python不完全支持面向对象程序设计_Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】...

    本文实例讲述了Python面向对象程序设计OOP.分享给大家供大家参考,具体如下: 类是Python所提供的最有用的的工具之一.合理使用时,类可以大量减少开发的时间.类也在流行的Python工具中使用 ...

  4. python编程从入门到实战类的定义_Python编程:从入门到实践—类

    创建类 #!/usr/bin/env python # --*-- encoding:utf-8 --*-- class Dog(): """一次模拟小狗的简单尝试&qu ...

  5. python函数对变量的作用_python函数对变量的作用及遵循的原则

    1.全局变量和局部变量 全局变量:指在函数之外定义的变量,一般没有缩进,在程序执行的全过程有效 局部变量:指在函数内部使用的变量,仅在函数内部有效,当函数退出时变量将不存在 例如: 1 n=1 #n是 ...

  6. java中math类的作用_Java开发知识之Java的数字处理类Math类

    Java开发知识之Java的数字处理类Math类 一丶Java.text.DecimalFormat类与NumberFormat类 首先 Java.text.DecimalFormat指的是Decim ...

  7. python里object是什么类型_Python中的object这个叫做基类的类,它的属性和行为都有哪些?...

    声明:以下仅为个人学习Python过程中总结的比较自洽的理解,事实上Python面向对象模型可能没那么简单.经查阅,Python在以前的版本还有不继承自object的类,叫做经典类. 用dir(obj ...

  8. python在实际中的作用_Python面向对象中__init__的实际作用是什么?

    给个知乎的连接吧,知乎的例子说的应该是: 设计模式六大原则之一:迪米特法则,一个对象应该对其他对象保持最少的了解.如果类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大. ...

  9. python中格式化字符串的作用_python中字符串格式化的意义(化妆)

    格式 描述 %%百分号标记 #就是输出一个% %c字符及其ASCII码 %s字符串 %d有符号整数(十进制) %u无符号整数(十进制) %o无符号整数(八进制) %x无符号整数(十六进制) %X无符号 ...

最新文章

  1. firefox推荐插件
  2. GreenDao 3.x 注解中ToOne和ToMany的个人理解
  3. Javascript日期格式化指定格式的字符串实现
  4. jQuery接收后台返回的数据
  5. 停止了IIS服务为什么apache还是启动不了呢?
  6. 安装cuda 非root_linux非root用户下安装软件,搭建生产环境
  7. 十一款游戏教你学会 CSS!
  8. 恐怖logo效果展示AE模板
  9. Edge浏览器安装Tampermonkey插件
  10. BugKu_MISC_(3)
  11. 自动换挡型数字频率计
  12. 路由器不同网段虚拟服务器设置,局域网中不同网段互访?静态路由表必须要学会设置...
  13. 什么蓝牙耳机最好用?公认好用性价比高的蓝牙耳机推荐
  14. 2021年安全员-B证最新解析及安全员-B证考试平台
  15. find vba 模糊_EXCEL——VBA实现模糊查找并获取查找到的单元格内容
  16. python分析红楼梦中人物形象_《红楼梦》中女性人物形象分析
  17. TTN服务器LoRaWAN网关配置流程
  18. 【IPD】IPDPLM
  19. 分享一组Rpg Marker人物行走,游戏素材图片,共20张图片
  20. 绝地求生玩家排名预测

热门文章

  1. static和extern的用法总结
  2. html字体加大标签与写法介绍
  3. Swift 里集合类型协议的关系
  4. Selenium断言的使用,等待
  5. Window系统下安装Redis
  6. .net MVC路由
  7. cocoapods 命令
  8. 别人叫我程序猿,我称自己攻城狮。没日没夜写代码,不知何日涨工资?
  9. Dynamic programming solving ULS
  10. 单线程会导致死锁吗?