特設多型
多型 |
---|
特設多型 |
參數多型 |
子類型 |
特設多型(ad hoc polymorphism)是程式語言的一種多型,多型函數有多個不同的實現,依賴於其實參而呼叫相應版本的函數。因此,特設多型僅支援有限數量的不同類型。函數多載乃至運算子多載也是特設多型的一種。
概述
特設多型與參數多型相對。ad hoc在這裏並不是貶義,而是指這類多型並不是型別系統的基本特性,不是像參數多型那樣適用於無窮多的類型,而是針對特定問題的解決方案。
換言之,參數多型對各模板參數的實現,是根據模板的通用(generically)的行為的抽象,即泛型的語意;而特設多型可以針對不同的版本實現完全不同的行為,或曰對於每個不同的模版參數都有單獨的版本來應對。打個比方:假如我們要把原材料切成兩半——
- 參數多型:只要能「切」,就用工具來切割它;
- 特設多型:根據原材料是鐵還是木頭還是什麼來選擇不同的工具來切。
歷史
特設多型的名字來源於其發明人克里斯托弗·斯特雷奇於1967年8月在哥本哈根的電腦程式設計暑期學校發表的著名論文《程式語言中的基礎概念》,該文首次提出了參數多型、特設多型、左值、右值等概念。[1]
早繫結
多型的早繫結(early binding)是在編譯期,編譯器完成多型的分派機制:把多型函數、多型類型的名字根據模板參數繫結到具體的模板實現。
晚繫結
多型的晚繫結是在執行期,程式確定即將要呼叫的多型函數的實現。Smalltalk實現了這種晚繫結機制。
例子
加法運算子+
假設可以運用到如下的情形:
1 + 2 = 3
3.14 + 0.0015 = 3.1415
1 + 3.7 = 4.7
[1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]
[true, false] + [false, true] = [true, false, false, true]
"bab" + "oon" = "baboon"
多載
為此,需要的多載實現:
- 第一種情形,需要整型加法;
- 第二、第三種情形,需要浮點型加法。其中第三種情形需要隱式類型轉換(type coercion)。
- 第四、第五種情形,需要list的連接操作;
- 第六種情形,需要字串字面量的連接操作。
因此,運算子名字+
實際上使用了三到四種完全不同的函數實現。
參考文獻
- ^ C. Strachey, Fundamental concepts in programming languages. Lecture notes for International Summer School in Computer Programming, Copenhagen, August 1967