Python面向对象--多态

一.多态

多态可以理解为同一个事物的多种形态,例如,生物可以分为动物和植物等,动物又可以有多种,

例如:

from abc import ABCMeta,abstractmethod
class Animal(metaclass=ABCMeta): #同一类事物:动物
    @abstractmethod
    def talk(self):
        pass

class People(Animal): #动物的形态之一:人
    def talk(self):
        print('say hello')

class Wolf(Animal): #动物的形态之二:狼
    def talk(self):
        print('say aohu')
View Code

二.多态性

多态性的概念其实不难理解,它是指对不同类型的变量进行相同的操作,它会根据对象(或类)类型的不同而表现出不同的行为。

# 在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息(!!!obj.func():是调用了obj的方法func,又称为向obj发送了一条消息func),不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
# 
# 比如:老师.下课铃响了(),学生.下课铃响了(),老师执行的是下班操作,学生执行的是放学操作,虽然二者消息一样,但是执行的效果不同
View Code

多态性分为静态多态性和动态多态性

静态多态性:如任何类型都可以用运算符+进行运算

动态多态性:不同的对象可以执行相同的方法

peo=People()
dog=Dog()

#peo、wolf都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们两者的具体是什么类型,而直接使用
peo.talk()
wolf.talk()


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


#人和狼都能使用talk

#总结:静态多态性一般指的的对象调用自己的属性,动态多态性一般指的是对象的方法

三.多态性的好处

1.增加了程序的灵活性

  以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)

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)
'''
View Code

四.鸭子模型

简介:

在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:
当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。从静态类型语言转向动态类型语言的用户通常试图添加一些静态的(在运行之前的)类型检查,从而影响了鸭子类型的益处和可伸缩性,并约束了语言的动态特性。

 

补充:Python天生多态性

例如:

Python的序列类型有多种形态:字符串,列表,元组,多态性体现如下

#str,list,tuple都是序列类型
s=str('hello')
l=list([1,2,3])
t=tuple((4,5,6))

#我们可以在不考虑三者类型的前提下使用s,l,t
s.__len__()
l.__len__()
t.__len__()

len(s)
len(l)
len(t)

 

 

 

 

 

 

 

 

 

posted @ 2018-03-05 15:13  明-少  阅读(130)  评论(0)    收藏  举报