埃尔法哥哥:Python编程教程:面向对象之高级特性( 五 )


四、面向对象三大特性-多态性(Polymorphism)
4.1多态性的概念
封装性 , 根据职责将属性和方法封装到一个抽象的类中? 定义类的准则
继承性 , 实现代码的重用 , 相同的代码不需要重复的编 写? 设计类的技巧? 子类针对自己特有的书需求 , 编写特定的代码
多态性 , 不同的子类对象 , 调用相同的父类方法 , 产生不同的执行结果? 多态可以增加代码的灵活性? 以继承和重写父类方法为前提? 是调用方法的技巧 , 不会影响到类的内部设计

埃尔法哥哥:Python编程教程:面向对象之高级特性
本文插图

示例代码:
"""
多态性:
继承和重写为前提 , 创建不同的对象执行的具体方法不同
"""
class Father(object):
def __init__(self, name):
print('父类的init方法')
self.name = name
def say(self):
print('父类的say方法' + self.name)
# Son类继承于Father类 , python中是类继承于类的
class Son(Father):
def __init__(self, name, age):
Father.__init__(self, name)
self.age = age
print('子类的init方法')
def say(self):
Father.say(self)
print('子类的say方法:' + self.name + ' , ' + str(self.age))
# 以下程序会体现出多态性
def mytest(obj):
obj.say()
f1 = Father("张爸爸")
mytest(f1)
print("---------------")
f2 = Son("小头儿子",5)
mytest(f2)
4.2属性和方法查找顺序
多态性(多态绑定)是在有继承背景情况下使用的一种特性.
是指在不考虑实例背景的情况下使用实例
多态的理论根据是属性和方法的查找过程. 只要使用 obj.attr 的方式使用属性和方法, 则查找顺序一定是: 对象本身, 类定义, 基类定义...
关于先查找对象本身的说明:因为 python 是一门动态语言, 允许我们在代码执行的过程中去动态的给对象添加属性和方法, 所以先从对象本身查找.
class Father:
def __init__(self, name):
self.name = name
def speak(self):
print("我是父类中的 speak 方法" + self.name)
# Son继承 Father 类
class Son(Father):
def __init__(self, name, age):
Father.__init__(self, name)
self.age = age
def speak(self):
Father.speak(self)
print("我是子类的 speak 方法" + self.name + " 年龄:" + str(self.age))
def foo():
print("我是动态添加上去的...")
s = Son("李四", 20)
s.speak = foo
s.speak()
4.3 鸭子类型
python 的多态有的时候很多人把它称之为 鸭子类型
鸭子类型是指: 看起来像鸭子, 叫起来像鸭子, 走起来像鸭子, 那么它既是鸭子, 你就可以把它当鸭子来用.
换成编程语言的说法就是: 对象属性和方法的时候完成时和类型分开的.
class A:
def speak(self):
print("a 类中的方法")
class B:
def speak(self):
print("b 类中的方法")
def foo(obj):
obj.speak()
a = A()
b = B()
foo(a)
foo(b)
说明:
foo 接受一个对象, 只要这个对象中有 speak() 方法, 就可以正常执行, 我们并不关注他的类型
A, B 这两个类没有任何的关系, 但是他们都有 speak 方法, 所以传递过去都没有任何的问题.
这就是鸭子模型, 只要你看起来有 speak 就可以了
五、其他
5.1 特殊属性__slot__5.1.1动态添加属性的问题
通过前面的学习中我们知道, 由于 python 的动态语言的特性, 我们可以动态的给对象添加属性和方法.


推荐阅读