Python的面向对象的三大特性之多态

HongKongPython 2020-05-12

一、什么是多态

多态的引入:奥迪、QQ、大卡车三种状态,我们学习如何开车,学会后不管什么车都会了吧

# 获取字符串长度
print(‘hello‘.__len__())
len(‘hello‘)
print([1,2,3].__len__())
len([1,2,3])
print({‘a‘:1}.__len__())
len({‘a‘:1})
print("="*50)
# 定义一个统一的接口
def my_len(val):
    return val.__len__()
print(my_len(‘hello‘))
print(my_len([1,2,3]))
print(my_len({‘a‘:1}))
什么是多态:同一种事物有多种不同形态,比如动物类中有:人,猫,狗,猪多态是在继承的背景之下衍生出的一种概念
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()

二、为何要有多态:多态会带来什么样的特性?多态性。

# 多态性:可以在不考虑对象具体类型的情况下而直接使用对象
class Animal:
    def say(self):
        print(‘动物基本的发声音。。。‘)

class People(Animal):
    def say(self):
        super().say()
        print("啊啊啊啊啊。。")

class Dog(Animal):
    def say(self):
        super().say()
        print(‘汪汪‘)

class Pig(Animal):
    def say(self):
        super().say()
        print(‘哼哼‘)

obj1 = People()
obj2 = Dog()
obj3 = Pig()

obj1.say()
obj2.say()
obj3.say()

print(‘=‘*50)
# 定义统一的接口,接受传入的动物对象,效果与上面的相同
def animal_say(animal):
    animal.say()

animal_say(obj1)
animal_say(obj2)
animal_say(obj3)

三、多态中的思想:其父类为了统一标准

python推崇的鸭子类型

# python推崇的是鸭子类型
# linux 一切皆是文件(对于文件操作一个读,一个写)
# 通过多态统一的思想格式把cpu 内存 txt文件做的像文件,对其进行操作
class Cpu:
    def read(self):
        print(‘cpu read‘)
    def write(self):
        print(‘cpu write‘)

class Mem: # 内存
    def read(self):
        print(‘mem read‘)
    def write(self):
        print(‘mem write‘)

class Txt:
    def read(self):
        print(‘txt read‘)
    def write(self):
        print(‘txt write‘)

# 统一使用
obj1 = Cpu()
obj2 = Mem()
obj3 = Txt()

obj1.read()
obj1.write()
obj2.read()
obj2.write()
obj3.read()
obj3.write()

四、了解的知识点

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

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

相关推荐