跳至內容

泛化函數

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書

計算機編程中,泛化函數(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).