泛化函数
在静态类型语言中
编辑在静态类型语言(比如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).