Python 語言中的 “鴨子型別”
提到 “鴨子型別”,就要先講講物件導向程式語言中的繼承和多型。
繼承
首先建立一個 Animal()
父類,父類繼承自 object
,object
是所有類都會繼承的類:
class Animal(object):
def run(self):
print("The animal is running...")
然後建立兩個子類,繼承自 Animal()
:
class Dog(Animal):
pass
class Cat(Animal):
pass
繼承的意思就是擁有所有父類的特性。這也是繼承的好處,實現了程式碼複用。所以,Dog()
和 Cat()
均有了 run()
方法:
dog = Dog()
dog.run()
cat = Cat()
cat.run()
--------------
The animal is running...
The animal is running...
對上面兩個子類進行一些程式碼修改:
class Dog(Animal):
def run(self):
print('The dog is running...')
class Cat(Animal):
def run(self):
print('The cat is running...')
執行結果如下:
dog = Dog()
dog.run()
cat = Cat()
cat.run()
--------------
The dog is running...
The cat is running...
可以看到子類的 run()
方法覆蓋了父類的 run()
方法。
多型
上面最後的執行結果,體現了多型的思想。即:動物裡面包含很多不同種類的動物,如:貓,狗,豬等等,但是它們有相同的特性就是跑,我們可以使用相同的方法來訪問它們。下面建立一個函式來體現多型:
class Animal(object):
def run(self):
print("The animal is running...")
class Dog(Animal):
def run(self):
print('The dog is running...')
class Cat(Animal):
def run(self):
print('The cat is running...')
def makeRun(animalType):
animalType.run()
dog = Dog()
cat = Cat()
makeRun(dog)
makeRun(cat)
輸出結果為:
The dog is running...
The cat is running...
鴨子型別
在程式設計中,鴨子型別(英語:duck typing)是動態型別的一種風格。在這種風格中,一個物件有效的語義,不是由繼承自特定的類或實現特定的介面,而是由"當前方法"方法 (電腦科學)")和屬性的集合"決定。這個概念的名字來源於由James Whitcomb Riley提出的鴨子測試,“鴨子測試”可以這樣表述:“當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就可以被稱為鴨子。” 在鴨子型別中,關注點在於物件的行為,能作什麼;而不是關注物件所屬的型別。-- 摘自鴨子型別的維基百科
對於上面的 makeRun()
函式來說,傳入的引數並不一定需要是 Animal
型別的,只需要保證傳入的物件有一個 run()
方法即可,如下面程式碼所示。這就是動態語言的“鴨子型別”,它並不要求嚴格的繼承體系,一個物件只要“看起來像鴨子,走起路來像鴨子”,那它就可以被看做是鴨子。
class Person(object):
def run(self):
print("The person is running...")
person = Person()
makeRun(person)
----------------------------
The person is running...
而在靜態語言中,如 Java ,如果需要傳入 Animal
型別,則傳入的物件就必須是 Animal
型別或者它的子類,否則,將無法呼叫 run()
方法。
參考
相關文章
- Python中的鴨子型別Python型別
- Python:多型、協議和鴨子型別Python多型協議型別
- Python 中的鴨子型別和猴子補丁Python型別
- python語言中基本資料型別有哪些?Python資料型別
- 通俗理解鴨子型別是幹什麼的型別
- C語言中的資料型別C語言資料型別
- go 語言中預設的型別識別Go型別
- c語言中陣列的三種型別C語言陣列型別
- 大話 python 之鴨子Python
- dart系列之:dart語言中的內建型別Dart型別
- Python語言中/與//的區別是什麼?Python
- 對C語言中無符號型別的建議C語言符號型別
- c語言中預設引數的兩種型別C語言型別
- Python語言中=和==有什麼區別?Python
- 語言型別介紹及其Python的語言型別型別Python
- c++語言中類的私有型別或保護型別成員變數C++型別變數
- C語言中幾種報錯型別的解決方案C語言型別
- python語言中類和函式的作用及區別!Python函式
- C語言中的複雜資料型別,你掌握了哪些?C語言資料型別
- 二進位制安全_C語言中資料型別C語言資料型別
- c語言中的資料型別的自動轉換原則C語言資料型別
- Python學習教程_Python語言中=和==有什麼區別?Python
- 【R語言入門】R語言中的變數與基本資料型別R語言變數資料型別
- Python語言中__init__與__new__的區別是什麼?Python
- C語言中,四則運算導致資料型別的轉換C語言資料型別
- R 語言中雙中括號 [[]]與資料型別列表的關係資料型別
- Python語言中的模組、包、庫之間有什麼區別?Python
- Kotlin語言中的泛型設計哲學Kotlin泛型
- Python語法--可變型別和不可變型別Python型別
- 【Python入門】12.物件導向程式設計之 三大特徵:封裝、繼承和多型 & 鴨子型別是什麼?...Python物件程式設計特徵封裝繼承多型型別
- python語言中如何使用註釋Python
- Python語言的全部資料型別分享!Python資料型別
- python---之編譯型語言和解釋型語言的區別Python編譯
- C語言中Pointer, Array,String and Structures的區別C語言Struct
- 33 個 JavaScript 核心概念系列(三): 顯式 (名義) 與 隱式 (鴨子)型別轉換JavaScript型別
- go語言中的封裝,繼承和多型Go封裝繼承多型
- Python屬於什麼型別的語言?Python影片課!Python型別
- c語言中%f輸出double型和float型值C語言