python 面向对象(4):继承&多态
2020-04-19 本文已影响0人
_百草_
# -*- coding:utf-8 -*-
"""
@author:wlh
@file:subClass_20200419.py
@time:2020/04/19
"""
# 从现有类中继承,新的类class称为subclass子类
# 被集成的类称为基类Base Class、父类或超类Super Class
class Animal(object):
def run(self):
print('Animal is running!')
def run_twice(self, animal):
animal.run()
# animal.run()
class Dog(Animal): # Dog 父类是Animal
pass
class Cat(Animal): # Cat 父类是Animal
def run(self):
print('Cat is running ...')
def eat(self): # 也可以为子类增加新的方法
print('Eating ...')
# 继承好处1:子类获取父类的全部功能,自动拥有run()方法
dog = Dog()
dog.run() # 输出结果:Animal is running!
# 继承好处2:代码改进,如Cat 类中的run()方法
cat = Cat()
cat.run() # 输出结果:Cat is running ...
cat.eat()
# 子类和父类中都存在相同的run()方法,子类覆盖了父类的run()
# 此时,调用子类,即为多态 [继承好处3]
'''
多态
定义一个class,其实定义了一种数据类型,与python中list等一样
'''
# 判断变量是否是某一类型
print(isinstance(cat, Animal)) # 输出结果:True
print(isinstance(cat, Cat)) # 输出结果:True
# -- cat不仅仅是Cat类,还是Animal类
# 即,在继承关系中,若一个实例的数据类型是某个子类,也可以被看做是父类;反之不成立
animal = Animal()
print(isinstance(animal, Cat)) # 输出结果:False
# animal是Animal类,不能看做Cat类
'''
新增一个类,不必对run_twice()方法修改
依赖Animal作为参数的函数或方法都可以不加修改地正常运行,原因在于多态
传入的任意类型,只要是Animal类或子类,就会自动调用实际类型的run()方法,这就是多态
'''
cat.run_twice(Animal()) # 输出结果:Animal is running!
cat.run_twice(Cat()) # 输出结果:Cat is running ...
# 开闭原则
# 对扩展开放:允许新增Animal子类
# 对修改封闭:不需要修改依赖Animal类型的run_twice()等函数
# 继承还可以一级一级的往下继承
# ----------------------------------------------
# 静态语言 & 动态语言
# 对于静态语言(如java)来说,如果传入Animal类型,则传入的对象必须是Animal类型或其子类,否则无法调用run()方法
# 对于动态语言(如python)来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就ok
class Student(object):
def run(self):
print('Student is running !')
cat.run_twice(Student()) # 输出结果:Student is running !
# --总结
# 继承:把父类的所用功能都直接拿过来,这样就不必重零做起
# 子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写
# 参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017497232674368