14.多态

面向对象的三大特性:封装、继承、多态
  • 封装:将数据和方法封装在一个类中
  • 继承:python中一个类可以继承一个或多个类,被继承的类叫父类/基类,继承的类叫子类
  • 多态:指的是一个类是有多种形态,一个抽象类有多个子类,所以多态的概念依赖于继承。表现于:不同的子类对象调用相同的方法时,会产生不同的执行结果。多态可以增加代码的灵活性
    比如说:继承Animal类的有cat类和dog类
注意:Python中函数的参数是没有类型限制的,所以多态在python中的体现并不是很严谨。多态的概念是应用于java和c#这类强类型语言中,而python只有“鸭子类型”(所以,python没有多态)


  • 鸭子类型的体现:(面试)
    1.静态语言:对于静态语言(比如java),上面例子中,传入对象的类型必须是Animal类或者它的子类。否则会报错,并无法执行run()方法
    2.动态语言:对于动态语言(比如python),上面例子中,传入对象的类型不需要是Animal类或者它的子类。只要传入的这个类或它的父类实现了run()方法,都能够调用run()方法【鸭子类型的体现】

  • 多态的意义:开放封闭原则(面试)
    1.对于一个变量,我们只需要知道它是Base类型,无需确切知道它的子类型,就可以放心地调用共有的方法(比如上面的run())。调用方只管调用,不需要管实现细节。
    2.当需要新增功能时,只需要新增一个Base类的子类去实现这个新增的功能,就可以在原来的基础上进行功能的扩展,这就是“开放封闭”原则
    a.对扩展开放:允许新增Base子类,以及重写Base类的方法
    b.对修改封闭:不需要修改Base类已实现的函数

  • 下面代码是“伪多态”,述说下多态的例子以及多态的作用

class Animal(object):
    def run(self):
        print('动物都会跑')


# 都是继承Animal类,但是有不同的形态
class Cat(Animal):
    def run(self):
        print('猫还会爬树')


class Dog(Animal):
    def run(self):
        print('狗不会爬树')


print(isinstance(Cat(), Animal))  # True
print(isinstance(Dog(), Animal))  # True


"""多态的作用"""

# 定义一个函数,用于接收Animal类型的对象,包括其子类
def func(obj):  # 这里在强类型语言中,需要限制传入参数的类型。比如说 public static void func(Animal animal){...}
    obj.run()


# 这个时候,分别传入Cat类和Dog类,会根据不同的对象执行不同的事情
# 这就是多态的体现


func(Cat())  # 猫还会爬树
func(Dog())  # 狗不会爬树


# 接着再定义一个类,也继承Animal方法,但是没有run方法
class Bird(Animal):
    pass


# 这时候把这个类传入到刚才的func()类中
# 依旧能运行,调用了父类Animal类的run()方法
func(Bird())  # 动物都会跑

你可能感兴趣的:(14.多态)