泛化函數
多態 |
---|
特設多態 |
參數多態 |
子類型 |
在計算機編程中,泛化函數(generic function)或譯泛型函數,是為多態而定義的函數。
在靜態類型語言中
[編輯]在靜態類型語言(比如C++和Java)中,術語「泛型函數」,指稱一種叫做泛型編程的編譯時間多態機制(靜態分派),特別是參數多態。它們是使用類型參數定義的函數,意圖用編譯時間類型信息來解決它。編譯器使用這些類型來實例化適合的版本,適當的解決任何函數重載。
在Common Lisp對象系統中
[編輯]在某些面向對象編程系統,比如Common Lisp對象系統(CLOS)[1]和Dylan中,泛化函數是一個實體,由具有相同名字的所有方法組成。泛化函數典型的是從function
和standard-object
二者繼承而來的類的實例。因此泛化函數是函數(可以被調用而應至實際參數)和正常對象二者。圖書《元對象協議的藝術》詳細解釋了CLOS泛化函數的實現和使用。
Lisp的早期面向對象編程擴展是Flavors[2]。它受Smalltalk影響,而使用平常的消息發送范型。發送一個消息的Flavors語法是:
(send object :message)
對於New Flavors[3],它決定message
應當是真正的函數,並使用常規函數調用語法:
(message object)
message
現在是泛化函數,是一個對象並且自身就是函數。message
的個體實現叫做方法。
相同的想法實現於CommonLoops之中[4]。New Flavors和CommonLoops,是Common Lisp對象系統的主要影響者。
例子
[編輯]Common Lisp
[編輯]下面在SBCL中定義一個泛化函數,有兩個形式參數object-1
和object-2
。這個泛化函數的名字是collide
:
(defgeneric collide (object-1 object-2))
屬於這個泛化函數的方法定義在類之外。這裡為泛化函數collide
定義一個方法,它特定於類asteroid
(第一個形式參數object-1
)和類spaceship
(第二個形式參數object-2
)。形式參數在方法體內作為正常變量使用。沒有訪問類槽的特殊命名空間:
(defclass asteroid () ())
(defclass spaceship () ())
(defmethod collide ((object-1 asteroid) (object-2 spaceship))
(format t "asteroid ~a collides with spaceship ~a" object-1 object-2))
調用泛化函數:
* (collide (make-instance 'asteroid) (make-instance 'spaceship))
asteroid #<ASTEROID {1001959923}> collides with spaceship #<SPACESHIP {1001959963}>
NIL
Common Lisp還可以檢索一個泛化函數的個體方法。FIND-METHOD
從泛化函數collide
找到特定於類asteroid
和spaceship
的方法。
* (find-method #'collide nil (list (find-class 'asteroid) (find-class 'spaceship)))
#<STANDARD-METHOD COMMON-LISP-USER::COLLIDE (ASTEROID SPACESHIP) {1001939333}>
比較於其他語言
[編輯]泛化函數粗略的對應於Smalltalk術語方法,但具有顯著的例外,在Smalltalk的單一分派中,接收者的類,是調用哪個代碼體的唯一確定者,與實際參數的類型或值無關。在具有多分派的編程語言中,在調用一個泛化函數的時候,方法分派在所有實際參數的基礎之上發生,不只是有特權的那個實際參數。New Flavors也提供了泛化函數,但只有單一分派。
引用
[編輯]- ^ The Common Lisp Object System: An Overview (PDF). [2021-03-27]. (原始內容存檔 (PDF)於2021-03-24).
- ^ Howard Cannon, Flavors: A non-hierarchical approach to object-oriented programming (頁面存檔備份,存於網際網路檔案館), Symbolics Inc., 1982
- ^ David A. Moon, S Keene. New Flavors. Proceedings of ACM Conf. Object-Oriented Programming, Systems (ACM 1986 OOPSLA Conference). 1986.
- ^ CommonLoops, Merging Lisp and Object-Oriented Programming (PDF). [2009-12-10]. (原始內容 (PDF)存檔於2011-06-04).