Generische Funktion - Generic function

In der Computerprogrammierung ist eine generische Funktion eine für den Polymorphismus definierte Funktion .

In statisch typisierten Sprachen

In statisch typisierten Sprachen (wie C ++ und Java ) bezieht sich der Begriff generische Funktionen auf einen Mechanismus für den Polymorphismus zur Kompilierungszeit ( statischer Versand ), insbesondere den parametrischen Polymorphismus . Dies sind Funktionen, die mit TypeParameters definiert wurden und mit Informationen zum Typ der Kompilierungszeit aufgelöst werden sollen . Der Compiler verwendet diese Typen, um geeignete Versionen zu instanziieren und etwaige Funktionsüberladungen entsprechend zu beheben .

Im Common Lisp Object System

In einigen Systemen für die objektorientierte Programmierung wie dem Common Lisp Object System (CLOS) und Dylan ist eine generische Funktion eine Entität, die aus allen Methoden mit demselben Namen besteht. In der Regel ist eine generische Funktion eine Instanz einer Klasse, die sowohl von der Funktion als auch vom Standardobjekt erbt . Generische Funktionen sind also sowohl Funktionen (die mit Argumenten aufgerufen und auf diese angewendet werden können) als auch gewöhnliche Objekte. Das Buch Die Kunst des Metaobjektprotokolls erklärt die Implementierung und Verwendung von generischen CLOS-Funktionen im Detail.

Eine der frühen objektorientierten Programmiererweiterungen von Lisp ist Flavours . Es wurde das übliche von Smalltalk beeinflusste Paradigma für das Senden von Nachrichten verwendet . Die Flavours-Syntax zum Senden einer Nachricht lautet:

 (send object :message)

Bei New Flavours wurde entschieden, dass die Nachricht eine echte Funktion sein sollte und die übliche Funktionsaufrufsyntax verwendet werden sollte:

 (message object)

Nachricht ist jetzt eine generische Funktion , ein Objekt und eine Funktion für sich. Einzelne Implementierungen der Nachricht werden als Methoden bezeichnet .

Die gleiche Idee wurde in CommonLoops implementiert . Neue Aromen und CommonLoops waren der Haupteinfluss für das Common Lisp Object System.

Beispiel

Common Lisp

Definieren Sie eine generische Funktion mit zwei Parametern Objekt-1 und Objekt-2. Der Name der generischen Funktion lautet kollidieren .

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

Methoden, die zur generischen Funktion gehören, werden außerhalb von Klassen definiert. Hier definieren wir eine Methode für die generische Funktionskollision , die auf die Klassen Asteroid (erster Parameter Objekt-1) und Raumschiff (zweiter Parameter Objekt-2) spezialisiert ist. Die Parameter werden als normale Variablen innerhalb des Methodenkörpers verwendet. Es gibt keinen speziellen Namespace, der Zugriff auf Klassensteckplätze hat.

 (defmethod collide ((object-1 asteroid) (object-2 spaceship))
   (format t "asteroid ~a collides with spaceship ~a" object-1 object-2))

Aufruf der generischen Funktion:

? (collide (make-instance 'asteroid) (make-instance 'spaceship))
asteroid #<ASTEROID 4020003FD3> collides with spaceship #<SPACESHIP 40200048CB>

Common Lisp kann auch einzelne Methoden aus der generischen Funktion abrufen. FIND-METHOD findet die Methode aus der generischen Funktion kollidieren, die auf die Klassen Asteroid und Raumschiff spezialisiert ist .

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

Vergleich mit anderen Sprachen

Generische Funktionen entsprechen in etwa den Methoden von Smalltalk- Begriffen , mit der bemerkenswerten Ausnahme, dass in Smalltalk die Klasse des Empfängers die einzige Determinante dafür ist, welcher Codekörper aufgerufen wird: Die Typen oder Werte der Argumente sind irrelevant ( Einzelversand ). In einer Programmiersprache mit Mehrfachversand, wenn eine generische Funktion aufgerufen wird, erfolgt der Methodenversand auf der Grundlage aller Argumente, nicht nur eines, das privilegiert ist. New Flavours bot auch generische Funktionen, jedoch nur einen einzigen Versand.

Verweise