泛化函數
在靜態型別語言中
編輯在靜態型別語言(比如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).