本页使用了标题或全文手工转换

泛化函数

维基百科,自由的百科全书
跳到导航 跳到搜索

计算机编程中,泛化函数(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)。它受Smalltalk影响而使用平常的消息发送范型。发送一个消息的Flavors语法是:

 (send object :message)

对于New Flavors,它决定message应当是真正的函数并使用常规函数调用语法:

 (message object)

message现在是泛化函数,是一个对象并且自身就是函数。message的个体实现叫做方法。

相同的想法实现于CommonLoops英语CommonLoops之中[2]。New Flavors和CommonLoops是Common Lisp对象系统的主要影响者。

例子[编辑]

Common Lisp[编辑]

定义一个泛化函数,有两个形式参数object-1object-2。这个泛化函数的名字是collide

 (defgeneric collide (object-1 object-2))

属于这个泛化函数的方法定义在类之外。这里为泛化函数collide定义一个方法,它特定于类asteroid(第一个形式参数object-1)和spaceship(第二个形式参数object-2)。形式参数在方法体内作为正常变量使用。没有访问类槽的特殊命名空间:

 (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 4020003FD3> collides with spaceship #<SPACESHIP 40200048CB>

Common Lisp还可以检索一个泛化函数的个体方法。FIND-METHOD从泛化函数collide找到特定于类asteroidspaceship的方法。

? (find-method #'collide nil (list (find-class 'asteroid) (find-class 'spaceship)))
#<STANDARD-METHOD COLLIDE NIL (ASTEROID SPACESHIP) 4150015E43>

比较于其他语言[编辑]

泛化函数粗略的对应于Smalltalk术语方法,但具有显著的例外,在Smalltalk中,接收者的类是调用哪个代码体的唯一确定者:实际参数的类型或值是无关的(单一分派)。在具有多分派的编程语言中,在调用一个泛化函数的时候,方法分派在所有实际参数的基础之上发生,不只是有特权的那个实际参数。New Flavors英语Flavors (programming language)也提供了泛化函数,但只有单一分派。

引用[编辑]