面向對象之多態與多態性
阿新 • • 發佈:2018-03-23
strac writing sof 方式 更改 div read abc UNC
一、多態
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__()方法
面向對象之多態與多態性