面向对象之多态与多态性

一、多态

  1、定义:指的是一类事物的多种形态,如水有液体、气体和固体三种形态, 动物有人、猫、狗等存在形态。

  2、示例:

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

import abc
class Animal(metaclass=abc.ABCMeta): # 同一类事物
    @abc.abstractmethod
    def eat(self):
        pass
class People(Animal): # 动物形态一:人
    def eat(self):
        print('people is eating')
class Dog(Animal): # 动物形态二:狗
    def eat(self):
        print('dog is eating')
class Cat(Animal): # 动物形态三:猫
    def eat(self):
        print('cat is eating')
person = People()
dog = Dog()
cat = Cat()

二、多态性

  1、定义:指的是可以在不考虑对象的类型的情况下而直接使用对象。

  2、多态性的类型可分为静态多态性和动态多态性。

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

    动态多态性(通过示例来说明)

person = People()
dog = Dog()
cat = Cat()

#person、dog、cat都是动物,所以是动物肯定有eat方法
# 于是我们可以不用考虑它们三者的具体是什么类型,而可以直接使用

person.eat()
dog.eat()
cat.eat()

# 因此,更近一步,我们可以定义一个统一的接口来使用
# 动物类的通用方法,而不需要区分动物的形态种类,比如学开车,学了一种车,可以开奥迪、宝马等其他车,而不需要每个单独学

def  func(animal):
      animal.eat()   
func(person)
    

   3、多态性的好处 

  1、增加了程序的灵活性,以不变应万变,不论对象怎么变化,使用者都以同一种形式去调用,比如:func(animal)
  2、增加了程序的可扩展性,比如通过继承Animal类,使用者无需更改自己的代码,还是用func(animal)去调用   
# 通过继承Animal类创建一个新的类,使用者无需更改自身代码,仍然使用func(person)去调用

class Bird(Animal):  # 属于动物的另一种形态:鸟
    
    def  eat(self):
        print("I'm eating")

def func(animal):  #对于使用者而言,自身代码无需更改
    animal.eat()

bird1 = Bird() # 实例出一只鸟
func(bird1)  # 调用方式也无需改变,就能调用鸟的eat功能

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

三、鸭子类型

  1、鸭子类型:Python崇尚鸭子类型,即“如果看起来像,叫声像,而且走起路来像鸭子,那么它就是鸭子。”

   实例1:

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

class Textfile:
    def read(self):
        print('reading')
    def write(self):
        print('writing')
class Diskfile:
    def read(self):
        print('reading')
    def write(self):
        print('writing')
textfile = Textfile()
textfile.read()
diskfile = Diskfile()
diskfile.read()

    注意:尽管Textfile类和Diskfile类都没有继承内置文件对象的方法,但Textfile和Diskfile看起来都像是文件,因而都可以当作文件一样使用文件的read方法。

    示例2:

#!/usr/bin/env python3
#-*- coding:utf-8 -*-

# list、tuple、str都是序列类型
l = list([1,2,3])
t = tuple(('h','y','s','t'))
s = str('ht514')

# 使用内置方法
print(l.__len__()) # 3
print(t.__len__()) # 4
print(s.__len__()) # 5

# 等同于下列自定义调用方法
def len(func):
    return func.__len__()
print(len(l)) # 3
print(len(t)) # 4
print(len(s)) # 5

# list、tuple、str没有继承同一个父类,但看起来都像序列,就都可以调用__len__()方法
原文地址:https://www.cnblogs.com/schut/p/8629771.html