電腦編程中,泛化函數(generic function)或譯泛型函數,是為多型而定義的函數。

在靜態型別語言中

編輯

在靜態型別語言(比如C++Java)中,術語「泛型函數」,指稱一種叫做泛型編程的編譯時間多型機制(靜態分派英語Static dispatch),特別是參數多型。它們是使用類型參數英語TypeParameter定義的函數,意圖用編譯時間類型資訊來解決它。編譯器使用這些類型來實例化適合的版本,適當的解決任何函數多載

在Common Lisp對象系統中

編輯

在某些物件導向程式設計系統,比如Common Lisp對象系統(CLOS)[1]Dylan中,泛化函數是一個實體,由具有相同名字的所有方法組成。泛化函數典型的是從functionstandard-object二者繼承而來的類別的實例。因此泛化函數是函數(可以被呼叫而應至實際參數)和正常對象二者。圖書《元對象協定的藝術英語The Art of the Metaobject Protocol》詳細解釋了CLOS泛化函數的實現和使用。

Lisp的早期物件導向程式設計擴充是Flavors英語Flavors (programming language)[2]。它受Smalltalk影響,而使用平常的訊息傳送範式。傳送一個訊息的Flavors語法是:

 (send object :message)

對於New Flavors[3],它決定message應當是真正的函數,並使用常規函數呼叫語法:

 (message object)

message現在是泛化函數,是一個對象並且自身就是函數。message的個體實現叫做方法。

相同的想法實現於CommonLoops英語CommonLoops之中[4]。New Flavors和CommonLoops,是Common Lisp對象系統的主要影響者。

例子

編輯

Common Lisp

編輯

下面在SBCL中定義一個泛化函數,有兩個形式參數object-1object-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找到特定於類asteroidspaceship的方法。

* (find-method #'collide nil (list (find-class 'asteroid) (find-class 'spaceship)))
#<STANDARD-METHOD COMMON-LISP-USER::COLLIDE (ASTEROID SPACESHIP) {1001939333}>

比較於其他語言

編輯

泛化函數粗略的對應於Smalltalk術語方法,但具有顯著的例外,在Smalltalk的單一分派中,接收者的類,是呼叫哪個代碼體的唯一確定者,與實際參數的類型或值無關。在具有多分派的程式語言中,在呼叫一個泛化函數的時候,方法分派在所有實際參數的基礎之上發生,不只是有特權的那個實際參數。New Flavors英語Flavors (programming language)也提供了泛化函數,但只有單一分派。

參照

編輯
  1. ^ The Common Lisp Object System: An Overview (PDF). [2021-03-27]. (原始內容存檔 (PDF)於2021-03-24). 
  2. ^ Howard Cannon, Flavors: A non-hierarchical approach to object-oriented programming頁面存檔備份,存於互聯網檔案館), Symbolics Inc., 1982
  3. ^ David A. Moon英語David A. Moon, S Keene. New Flavors. Proceedings of ACM Conf. Object-Oriented Programming, Systems (ACM 1986 OOPSLA Conference). 1986. 
  4. ^ CommonLoops, Merging Lisp and Object-Oriented Programming (PDF). [2009-12-10]. (原始內容 (PDF)存檔於2011-06-04).