首页 > 其他分享 >多态性与鸭子类型

多态性与鸭子类型

时间:2023-05-07 21:11:43浏览次数:44  
标签:多态性 self 鸭子 Animal 类型 talk class def

多态与多态性

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

class Animal: #同一类事物:动物
    def talk(self):
        pass
class Cat(Animal): #动物的形态之一:猫
    def talk(self):
        print('喵喵喵')
class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('汪汪汪')
class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('哼哼哼')
 
#实例化得到三个对象
>>> cat=Cat()
>>> dog=Dog()
>>> pig=Pig()

多态性指的是可以在不用考虑对象具体类型的情况下而直接使用对象,这就需要在设计时,把对象的使用方法统一成一种:例如cat、dog、pig都是动物,但凡是动物肯定有talk方法,于是我们可以不用考虑它们三者的具体是什么类型的动物,而直接使用

>>> cat.talk()
喵喵喵
>>> dog.talk()
汪汪汪
>>> pig.talk()
哼哼哼

更进一步,我们可以定义一个统一的接口来使用

>>> def Talk(animal):
...     animal.talk()
... 
>>> Talk(cat)
喵喵喵
>>> Talk(dog)
汪汪汪
>>> Talk(pig)
哼哼哼

Python中一切皆对象,本身就支持多态性

# 我们可以在不考虑三者类型的情况下直接使用统计三个对象的长度
s.__len__()
l.__len__()
t.__len__()
 
# Python内置了一个统一的接口
len(s)
len(l)
len(t)

多态性的好处在于增强了程序的灵活性和可扩展性,比如通过继承Animal类创建了一个新的类,实例化得到的对象obj,可以使用相同的方式使用obj.talk()

>>> class Wolf(Animal): #动物的另外一种形态:狼
...     def talk(self):
...         print('嗷...')
... 
>>> wolf=Wolf() # 实例出一头狼
>>> wolf.talk() # 使用者根本无需关心wolf是什么类型而调用talk
嗷...

综上我们得知,多态性的本质在于不同的类中定义有相同的方法名,这样我们就可以不考虑类而统一用一种方式去使用对象,可以通过在父类引入抽象类的概念来硬性限制子类必须有某些方法名

import abc
 
# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法
    def talk(self): # 抽象方法中无需实现具体的功能
        pass
 
class Cat(Animal): # 但凡继承Animal的子类都必须遵循Animal规定的标准
    def talk(self):
        pass
 
cat=Cat() # 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化

但其实我们完全可以不依赖于继承,只需要制造出外观和行为相同对象,同样可以实现不考虑对象类型而使用对象,这正是Python崇尚的“鸭子类型”(duck typing):“如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子”。比起继承的方式,鸭子类型在某种程度上实现了程序的松耦合度,如下

#二者看起来都像文件,因而就可以当文件一样去用,然而它们并没有直接的关系
class Txt: #Txt类有两个与文件类型同名的方法,即read和write
    def read(self):
        pass
    def write(self):
        pass
 
class Disk: #Disk类也有两个与文件类型同名的方法:read和write
    def read(self):
        pass
    def write(self):
        pass

标签:多态性,self,鸭子,Animal,类型,talk,class,def
From: https://www.cnblogs.com/ycmyay/p/17380161.html

相关文章

  • 数据类型及常用方法
    引入我们学习变量是为了让计算机能够像人一样去记忆事物的某种状态,而变量的值就是用来存储事物状态的,很明显事物的状态分成不同种类的(比如人的年龄,身高,职位,工资等等),所以变量值也应该有不同的类型,例如salary=3.1#用浮点型去记录薪资age=18#用整型去记录年龄name='lil......
  • Java多态性
    Java多态性面向对象三大特征:封装性,继承性,多态性.extends继承或者implements实现,是多态的前提一个对象拥有多种形态这就是:对象的多态性多态的实现代码中体现多态性:父类引用指向子类对象格式父类名称对象名=new子类名称();或者接口名称对象名=new实现类......
  • C++虚函数详解:多态性实现原理及其在面向对象编程中的应用
    在面向对象的编程中,多态性是一个非常重要的概念。多态性意味着在不同的上下文中使用同一对象时,可以产生不同的行为。C++是一种面向对象的编程语言,在C++中,虚函数是实现多态性的关键什么是虚函数虚函数是一个在基类中声明的函数,它可以被子类重写并提供不同的实现。在C++中,使用关......
  • Linux下七种文件类型、文件属性及其查看方法
    1、七种文件类型普通文件类型Linux中最多的一种文件类型,包括纯文本文件(ASCII);二进制文件(binary);数据格式的文件(data);各种压缩文件.第一个属性为[-]目录文件就是目录,能用#cd命令进入的。第一个属性为[d],例如[drwxrwxrwx]块设备文件块设备文件:就是存储数据以......
  • k10_java数据类型
    数据类型强类型语言java是强类型语言要求变量的使用过要严格符合规定,所有的变量需要先定义后才能使用。弱类型语言就是类型定义不太严格,变量名可以不可以直接使用,或者直接定义个变量名,不用声明其类型java数据类型分类————Java的数据类型分为两类基本数......
  • 数据湖Iceberg-FlinkSQL-kafka类型表数据无法成功写入(6)
    数据湖Iceberg-简介(1)数据湖Iceberg-存储结构(2)数据湖Iceberg-Hive集成Iceberg(3)数据湖Iceberg-SparkSQL集成(4)数据湖Iceberg-FlinkSQL集成(5)数据湖Iceberg-FlinkSQL-kafka类型表数据无法成功写入(6)数据湖Iceberg-FlinkDataFrame集成(7)数据湖Iceberg-FlinkSQL-kafka类型表......
  • redis之五种基本数据类型
    0.前言本文主要讲解redis的五种基本数据类型:String、List、Set、SortedSet、Hash。学习如何使用它们,并且了解它们的底层数据结构实现,这样我们才能在适当的应用场景选择最适合的数据类型来解决我们的需求。1.String1.1简单使用String是redis最简单的且最常用的数据类型,可以......
  • oracle中int类型和number类型区别
    oracle中int类型和number类型区别 INT类型是NUMBER类型的子类型。下面简要说明:(1)NUMBER(P,S)该数据类型用于定义数字类型的数据,其中P表示数字的总位数(最大字节个数),而S则表示小数点后面的位数。假设定义SAL列为NUMBER(6,2)则整数最大位数为4位(6-2=4),而小数最大位数为2位。(2)INT类型当定......
  • 浅谈C#中动态类型与值类型装拆箱问题
    C#中的值类型封箱、开箱与动态类型的关系封箱和开箱是C#中两个重要的概念,它们涉及到值类型和引用类型在编译七和运行时的处理方式。动态类型是C#4.0引入的一个新特性,它允许在编译时不指定类型,而在运行时动态绑定类型。本文将简要介绍封箱、开箱和动态类型的概念,以及装拆箱与动态......
  • 计算机系统基础----特殊类型(数组,结构体 ,联合体)的分配
    《数组》《数组的分配与访问》首先我们要知道在8086中内存的结构如图: 可见一个单元格有8bit(1B) 对于指针类型数据占4字节,char占1个字节,int占4个字节,short占2个字节,double占8个字节 当我们访问数组中的数据时是要访存的,当要访存时,我们只知道数组的......