文档章节

面向对象三大特性——多态(含鸭子类型)

o
 osc_x4h57ch8
发布于 2018/04/24 15:04
字数 1037
阅读 0
收藏 0
def

精选30+云产品,助力企业轻松上云!>>>

一、多态概念

  在面向对象编程中,接口的多种不同的实现方式即为多态。多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

二、多态目的

  多态的目的就是实现接口重用

  多态指的是一类事物有多种形态。比如动物有多种形态:人、狗、猪。

import abc    #利用abc模块实现抽象类
class Animal(metaclass=abc.ABCMeta):  # 类似接口,只定义规范,不实现具体的代码
    @abc.abstractclassmethod
    def talk(self):
        pass

class People(Animal):  # 动物形态之一:人
    def talk(self):
        print('people is talking')

class Pig(Animal):     # 动物形态之二:猪
    def talk(self):
        print('Pig is talking')

class Dog(Animal):     # 动物形态之三:狗
    def talk(self):
        print('Dog is talking')

三、多态性

1、多态性概念

  多态性指在不考虑实例类型的情况下使用实例,多态性分为静态多态性和动态多态性。

  静态多态性:就是在系统编译期间就可以确定程序执行到这里将要执行哪个函数

  动态多态性:则是利用虚函数实现了运行时的多态,也就是说在系统编译的时候并不知道程序将要调用哪一个函数,只有在运行到这里的时候才能确定接下来会跳转到哪一个函数的栈帧。如下所示:

peo1 = People()
pig1 = Pig()
dog1 = Dog()
# 调用方法不用考虑三者具体是什么类型直接使用,这种就是动态多态性

# peo1.talk()
# pig1.talk()
# dog1.talk()


#更进一步,我们可以定义一个统一的接口来使用
def func(animal):
    animal.talk()

func(peo1)
func(pig1)
func(dog1)

  由上例可以看出,python本身就是支持多态性的。

2、多态性的好处

(1)增加程序的灵活性

      以不变应万变,无论对象千变万化,使用者都是同一种形式去调用

(2)增加程序的扩展性

      通过继承animal类创建一个新类,使用者可以不改变自己的代码,依然用func(animal)调用

>>> class Cat(Animal): #属于动物的另外一种形态:猫
...     def talk(self):
...         print('say miao')
... 
>>> def func(animal): #对于使用者来说,自己的代码根本无需改动
...     animal.talk()
... 
>>> cat1=Cat() #实例出一只猫
>>> func(cat1) #甚至连调用方式也无需改变,就能调用猫的talk功能
say miao

'''
这样我们新增了一个形态Cat,由Cat类产生的实例cat1,使用者可以在完全不需要修改自己代码的情况下。
使用和人、狗、猪一样的方式调用cat1的talk方法,即func(cat1)
'''

四、鸭子类型

  什么是鸭子类型(Duck Typing)?鸭子类型可解释为,如果一只动物,走起来像鸭子或者叫起来像鸭子,就可以把它当作鸭子。

  python崇尚一种鸭子类型,类与类之间不用共同继承一个父类,只需要将它们做得像一种事物即可。

例如,如果想编写现有对象的自定义版本。

  1、可以继承该对象

  2、可以创建一个外观和行为像,但与它无任何关系的全新对象(通常用于保存程序组件的松耦合度)

例1:利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法

class File:
    def read(self):
        pass

    def write(self):
        pass

class Disk:
    def read(self):
        print('disk read')

    def write(self):
        print('disk write')

class Text:
    def read(self):
        print('text read')

    def write(self):
        print('text write')


disk = Disk()
text = Text()

disk.read()
disk.write()

text.read()
text.write()
"""
disk read
disk write
text read
text write
"""
像文件的类

例2:序列类型有多种形态:字符串,列表,元组,但他们直接没有直接的继承关系

# 序列类型:列表list、元组tuple、字符串str
l = list([1, 2, 3])
t = tuple(('a', 'b'))
s = str('hello')

print(l.__len__())  # 3
print(t.__len__())  # 2
print(s.__len__())  # 5
像序列的类型

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

聊聊rocketmq-client-go的TraceInterceptor

序 本文主要研究一下rocketmq-client-go的TraceInterceptor TraceInterceptor rocketmq-client-go-v2.0.0/producer/interceptor.go // WithTrace support rocketmq trace: https://github.c......

go4it
22分钟前
0
0
如何在Android文本视图周围添加边框? - How do I put a border around an Android textview?

问题: 是否可以在textview周围绘制边框? 解决方案: 参考一: https://stackoom.com/question/EfXR/如何在Android文本视图周围添加边框 参考二: https://oldbug.net/q/EfXR/How-do-I-put...

法国红酒甜
37分钟前
10
0
设计模式(4) 建造者模式

什么是建造者模式 经典建造者模式的优缺点 对建造者模式的扩展 什么是建造者模式 建造者模式将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。创建者模式隐藏了...

zhixin9001
49分钟前
14
0
ArrayList源码分析 —— JDK8

ArrayList的特性 ArrayList内部使用数据作为存储结构,ArrayList可以理解为数组的扩展对象,封装了常用的和非常用的操作数组的方法。以及当数组长度不足以保存数组时,自动扩容数组,通常Arr...

XuePeng77
56分钟前
42
0
__slots__的用法? - Usage of __slots__?

问题: Python中__slots__的目的是什么-尤其是关于何时以及何时不使用它的目的? 解决方案: 参考一: https://stackoom.com/question/1ymu/slots-的用法 参考二: https://oldbug.net/q/1ym...

富含淀粉
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部