Vielfache Absendung

Vielfache Absendung oder Mehrmethoden oder Funktionsüberbelastung sind die Eigenschaft von einigen objektorientierten Programmiersprachen, auf denen eine Funktion oder Methode gestützt auf der Durchlaufzeit (dynamischer) Typ von mehr als einem seiner Argumente dynamisch entsandt werden können. Das ist eine Erweiterung der einzelnen Absendung polymorphism, wohin ein Methode-Anruf gestützt auf dem wirklichen abgeleiteten Typ des Gegenstands dynamisch entsandt wird, auf dem die Methode genannt worden ist. Vielfache Absendung verallgemeinert das dynamische Verschicken, um mit einer Kombination von zwei oder mehr Gegenständen zu arbeiten.

Das Verstehen der Absendung

Entwickler der Computersoftware organisieren normalerweise Quellcode in genannte Blöcke verschiedenartig genannte Unterprogramme, Verfahren, Unterprogramme, Funktionen oder Methoden. Der Code in der Funktion wird durch das Benennen davon - Durchführung eines Stückes des Codes durchgeführt das bringt in seinem Namen Verweise an. Das überträgt Kontrolle provisorisch der genannten Funktion; als die Ausführung der Funktion vollendet hat, wird Kontrolle normalerweise zurück der Instruktion im Anrufer übertragen, der der Verweisung folgt.

Funktionsnamen werden gewöhnlich ausgewählt, um vom Zweck der Funktion beschreibend zu sein. Es ist manchmal wünschenswert, mehreren Funktionen denselben Namen häufig zu geben, weil sie begrifflich ähnliche Aufgaben durchführen, aber auf verschiedenen Typen von Eingangsdaten funktionieren. In solchen Fällen ist die Namenverweisung an der Funktionsanruf-Seite nicht genügend, für den Block des durchzuführenden Codes zu identifizieren. Statt dessen werden die Zahl und der Typ der Argumente für den Funktionsanruf auch verwendet, um unter mehreren Funktionsdurchführungen auszuwählen.

Im "herkömmlichen", d. h. einzelne Absendung werden objektorientierte Programmiersprachen, wenn man eine Methode ("das Senden einer Nachricht" im Plausch anruft, "eine Mitglied-Funktion" in C ++ nennend), eines seiner Argumente besonders behandelt und verwendet, um zu bestimmen, welcher (potenziell viele) Methoden dieses Namens angewandt werden sollen. Auf vielen Sprachen wird das "spezielle" Argument syntaktisch angezeigt; zum Beispiel stellen mehrere Programmiersprachen das spezielle Argument vor einem Punkt im Bilden eines Methode-Anrufs: so dass ein Gebrüll erzeugen würde, wohingegen einen Pieps erzeugen würde.

Im Vergleich, auf Sprachen mit der vielfachen Absendung, ist die ausgewählte Methode einfach diejenige, deren Argumente die Zahl und den Typ des Funktionsanrufs vergleichen. Es gibt kein "spezielles" Argument, das die in einem besonderen Anruf ausgeführte Funktion/Methode "besitzt".

Common Lisp Object System (CLOS) ist ein frühes und wohl bekanntes Beispiel der vielfachen Absendung.

Datentypen

Wenn das Arbeiten mit Sprachen, die Datentypen während der Übersetzung unterscheiden können, unter den Alternativen auswählend, während der Übersetzung vorkommen kann. Die Tat, solche alternativen Funktionen für die Übersetzungszeit-Auswahl zu schaffen, wird gewöhnlich Überbelastung einer Funktion genannt.

Auf Programmiersprachen, die Datentyp-Identifizierung bis zur Durchlaufzeit aufschieben, muss die Auswahl unter alternativen Funktionen an der Durchlaufzeit vorkommen, die auf den dynamisch entschlossenen Typen von Funktionsargumenten gestützt ist. Auf Funktionen, deren alternative Durchführungen auf diese Weise ausgewählt werden, wird am meisten allgemein als Mehrmethoden verwiesen.

Es gibt einige mit dem dynamischen Verschicken von Funktionsanrufen vereinigte Laufzeitkosten. Auf einigen Sprachen kann die Unterscheidung zwischen Überbelastung und Mehrmethoden mit dem Bearbeiter verschmiert werden, der bestimmt, ob Übersetzungszeit-Auswahl auf einen gegebenen Funktionsanruf angewandt werden kann, oder ob langsamere Laufzeitabsendung erforderlich ist.

Beispiele

Das Unterscheiden vielfacher und einzelner Absendung kann klarer durch ein Beispiel gemacht werden. Stellen Sie sich ein Spiel vor, das, unter seinen (benutzersichtbaren) Gegenständen, Raumschiffen und Asteroiden hat. Wenn zwei Gegenstände kollidieren, muss das Programm eventuell verschiedene Sachen gemäß machen, was gerade was geschlagen hat.

Vielfache Absendungsbeispiele

Allgemeines Lispeln

Auf einer Sprache mit der vielfachen Absendung, wie Allgemeines Lispeln, könnte es mehr dem ähnlich sein:

(defmethod kollidieren - mit ((x Asteroid) (y Asteroid))

;; Geschäft mit Asteroid-Schlagen-Asteroiden

)

(defmethod kollidieren - mit ((x Asteroid) (y Raumschiff))

;; Geschäft mit Asteroid-Schlagen-Raumschiff

)

(defmethod kollidieren - mit ((x Raumschiff) (y Asteroid))

;; Geschäft mit Raumschiff-Schlagen-Asteroiden

)

(defmethod kollidieren - mit ((x Raumschiff) (y Raumschiff))

;; Geschäft mit Raumschiff-Schlagen-Raumschiff

)

</Quelle>

und ähnlich für die anderen Methoden. Ausführliche Prüfung und "dynamisches Gussteil" werden nicht verwendet.

In Gegenwart von der vielfachen Absendung wird die traditionelle Idee von Methoden, die als in Klassen und enthalten in Gegenständen definieren werden, weniger ansprechend — jeder kollidiert - mit der Methode dort wird zwei verschiedenen Klassen, nicht ein beigefügt. Folglich verschwindet die spezielle Syntax für die Methode-Beschwörung allgemein, so dass Methode-Beschwörung genau gewöhnlicher Funktionsbeschwörung ähnlich ist, und Methoden nicht in Klassen, aber in allgemeinen Funktionen gruppiert werden.

Pythonschlange

Auf Sprachen, die vielfache Absendung an der Sprachdefinition oder dem syntaktischen Niveau nicht unterstützen, ist es häufig möglich, vielfache Absendung mit einer Bibliothekserweiterung hinzuzufügen. Zum Beispiel stellt das Modul multimethods.py CLOS-artige Mehrmethoden für die Pythonschlange zur Verfügung, ohne die zu Grunde liegende Syntax oder Schlüsselwörter der Sprache zu ändern.

von Mehrmethoden importieren Absendung

von game_objects importieren Asteroiden, Raumschiff

von game_behaviors importieren ASFunc, SSFunc, SAFunc

kollidieren Sie = Absendung

kollidieren Sie ((Asteroid, Raumschiff), ASFunc) add_rule

kollidieren Sie ((Raumschiff, Raumschiff), SSFunc) add_rule

kollidieren Sie ((Raumschiff, Asteroid), SAFunc) add_rule

def AAFunc (a, b):

" ""Verhalten, wenn Asteroid Asteroiden""" schlägt

# definieren... neues Verhalten...

kollidieren Sie ((Asteroid, Asteroid), AAFunc) add_rule

</Quelle>
  1. ... später...

kollidieren Sie (thing1, thing2)

</Quelle>

Funktionell ist das dem CLOS Beispiel sehr ähnlich, aber die Syntax ist herkömmliche Pythonschlange.

Verwendende Pythonschlange 2.4 Raumausstatter, Guido van Rossum hat eine Beispieldurchführung von Mehrmethoden mit einer vereinfachten Syntax erzeugt:

@multimethod (Asteroid, Asteroid)

def kollidieren (a, b):

" ""Verhalten, wenn Asteroid Asteroiden""" schlägt # definieren... neues Verhalten...

@multimethod (Asteroid, Raumschiff)

def kollidieren (a, b):

" ""Verhalten, wenn Asteroid Raumschiff""" schlägt

# definieren... neues Verhalten...
  1. ... definieren Sie andere Mehrmethode-Regeln...
</Quelle>

und dann setzt es fort, den Mehrmethode-Raumausstatter zu definieren.

Pythonschlange mit MAXIMAL-REGELN

von peak.rules importieren Auszug, wenn

@abstract

def kollidieren (a, b):

"Prozess-Kollision von zwei Gegenständen"

@when (kollidieren (Asteroid, Asteroid))

def collide_asteroids (asteroid1, asteroid2):

Pass

@when (kollidieren (Raumschiff, Asteroid))

def collide_spaceship_with_asteroid (Raumschiff, Asteroid):

Pass

@when (kollidieren (Asteroid, Raumschiff))

def collide_asteroid_with_spaceship (Asteroid, Raumschiff):

geben Sie collide_spaceship_with_asteroid (Raumschiff, Asteroid) zurück

  1. usw...
</Quelle>

Beispiele, mit vielfacher Absendung wettzueifern

Java

Auf einer Sprache mit nur der einzelnen Absendung, wie Java, würde der Code wahrscheinlich etwas wie das schauen (obwohl das Besuchermuster helfen kann, dieses Problem zu beheben):

/* Beispiel, das Durchlaufzeit-Typ-Vergleich über Javas "instanceof" Maschinenbediener * / verwendet

verbinden Sie Collideable {\

/* das Bilden davon eine Klasse würde die Demonstration * / nicht ändern

Leere collideWith (Collideable anderer);

}\

Klassenasteroid führt Collideable {\durch

öffentliche Leere collideWith (Collideable anderer) {\

wenn (anderer instanceof Asteroid) {\

//behandeln Sie Kollision des Asteroid-Asteroiden

}\

sonst, wenn (anderes instanceof Raumschiff) {\

//behandeln Sie Kollision des Asteroid-Raumschiffes

}\

}\

}\

Klassenraumschiff führt Collideable {\durch

öffentliche Leere collideWith (Collideable anderer) {\ wenn (anderer instanceof Asteroid) {\

//behandeln Sie Kollision des Raumschiff-Asteroiden

}\ sonst, wenn (anderes instanceof Raumschiff) {\

//behandeln Sie Kollision des Raumschiff-Raumschiffes

}\ }\ }\</Quelle>

C

C hat dynamische Absendung nicht, so muss es manuell in einer Form durchgeführt werden. Häufig wird ein enum verwendet, um den Subtyp eines Gegenstands zu identifizieren. Dynamische Absendung kann durch das Aufblicken dieses Werts in einem Funktionszeigestock-Zweigtisch getan werden. Hier ist ein einfaches Beispiel in C:

Typedef-Leere (*CollisionCase) ;

Leere collision_AA {/* behandelt Asteroid-Asteroiden collision*/};

Leere collision_AS {/* behandelt Asteroid-Raumschiff collision*/};

Leere collision_SA {/* behandelt Raumschiff-Asteroiden collision*/};

Leere collision_SS {/* behandelt Raumschiff-Raumschiff collision*/};

typedef enum {\

Asteroid = 0,

Raumschiff

} Ding;

enum {\

num_thing_types = 2

};

CollisionCase collisionCases [num_thing_types] [num_thing_types] = {\

{&collision_AA, &collision_AS},

{&collision_SA, &collision_SS }\

};

Leere kollidiert (Ding a, Ding b) {\

(*collisionCases [b]) ;

}\

int Hauptsache {\

kollidieren Sie (Raumschiff, Asteroid);

}\</Quelle>

C ++

Während das Hinzufügen von ihnen zu C ++ betrachtet wird, zurzeit C ++ unterstützt nur einzelne Absendung heimisch. Die Methoden, um diese Beschränkung zu arbeiten, sind analog; jeder Gebrauch das Besuchermuster, verdoppeln Sie Absendung, dynamischen Wurf:

//Beispiel, das Durchlaufzeit-Typ-Vergleich über dynamic_cast verwendet

Struct-Ding {\

virtuelle Leere collideWith (Thing& anderer) = 0;

}\

Struct-Asteroid: Ding {\

Leere collideWith (Thing& anderer) {\

//dynamic_cast zu einem Zeigestock-Typ kehrt UNGÜLTIG zurück, wenn der Wurf fehlt

//(dynamic_cast zu einem Bezugstyp würde eine Ausnahme auf dem Misserfolg werfen)

wenn (Asteroid* Asteroid = dynamic_cast

//behandeln Sie Kollision des Asteroid-Asteroiden

} sonst wenn (Spaceship* Raumschiff = dynamic_cast

//behandeln Sie Kollision des Asteroid-Raumschiffes

} sonst {\

//Verzug-Kollision, die hier behandelt

}\ }\ }\

Struct-Raumschiff: Ding {\

Leere collideWith (Thing& anderer) {\ wenn (Asteroid* Asteroid = dynamic_cast //behandeln Sie Kollision des Raumschiff-Asteroiden } sonst wenn (Spaceship* Raumschiff = dynamic_cast //behandeln Sie Kollision des Raumschiff-Raumschiffes } sonst {\ //Verzug-Kollision, die hier behandelt }\ }\ }\</Quelle>

oder Nachschlagetabelle des Zeigestocks zur Methode:

  1. einschließen
einschließen

typedef nicht unterzeichneter uint4;

typedef nicht unterzeichneter langer langer uint8;

Klassending {\

geschützt:

Ding (const uint4 Kripo): tid (Kripo) {\

}\

const uint4 tid;//Typ id

Typedef-Leere (Ding::*CollisionHandler) (Thing& anderer);

typedef std:: hash_map

statische Leere addHandler (const uint4 id1, const uint4 id2, const Dressierer von CollisionHandler) {\

collisionCases.insert (CollisionHandlerMap:: value_type (Schlüssel (id1, id2), Dressierer));

}\

statischer uint8 Schlüssel (const uint4 id1, const uint4 id2) {\

geben Sie uint8 (id1) zurück

} sonst {\

//Verzug-Kollision, die behandelt

}\

}\};

Klassenasteroid: öffentliches Ding {\

Leere asteroid_collision (Thing& anderer) {/*handle Asteroid-Asteroid collision*/}\

Leere spaceship_collision (Thing& anderer) {/*handle Asteroid-Raumschiff collision*/}\

Publikum:

Asteroid : Ding (Kripo) {}\

statische Leere initCases ;

statischer const uint4 Kripo;

};

Klassenraumschiff: öffentliches Ding {\

Leere asteroid_collision (Thing& anderer) {/*handle Raumschiff-Asteroid collision*/}\

Leere spaceship_collision (Thing& anderer) {/*handle Raumschiff-Raumschiff collision*/}\

Publikum:

Raumschiff : Ding (Kripo) {\

}\ statische Leere initCases ;

statischer const uint4 Kripo;//Klasse id

};

Ding:: Ding von CollisionHandlerMap:: collisionCases;

const uint4 Asteroid:: Kripo = typeid (Asteroid).hash_code ;

const uint4 Raumschiff:: Kripo = typeid (Raumschiff).hash_code ;

leerer Asteroid:: initCases {\

addHandler (Kripo, Kripo, (CollisionHandler) &Asteroid::asteroid_collision);

addHandler (Kripo, Raumschiff:: Kripo, (CollisionHandler) &Asteroid::spaceship_collision);

}\

leeres Raumschiff:: initCases {\

addHandler (Kripo, Asteroid:: Kripo, (CollisionHandler) &Spaceship::asteroid_collision);

addHandler (Kripo, Kripo, (CollisionHandler) &Spaceship::spaceship_collision);

}\int Hauptsache {\

Asteroid:: initCases ;

Raumschiff:: initCases ;

Asteroid a1, a2;

Raumschiff s1, s2;

a1.collideWith (a2);

a1.collideWith (s1);

s1.collideWith (s2);

s1.collideWith (a1);

}\</Quelle>

Stroustrup erwähnt im Design und der Evolution von C ++, dass er das Konzept von Mehrmethoden gemocht hat und gedacht hat, es in C ++ durchzuführen, aber behauptet, unfähig gewesen zu sein, eine effiziente Beispieldurchführung (vergleichbar mit virtuellen Funktionen) zu finden und einige mögliche Typ-Zweideutigkeitsprobleme aufzulösen. Er setzt fort festzustellen, dass, obwohl die Eigenschaft noch nett sein würde zu haben, dass sie mit der doppelten Absendung oder einem Typ ungefähr durchgeführt werden kann, Nachschlagetabelle, wie entworfen, im C/C ++ gestützt hat, ist Beispiel oben auch eine niedrige Vorzugseigenschaft für zukünftige Sprachrevisionen.

Unterstützung auf Programmiersprachen

Programmiersprachen, die allgemeine Mehrmethoden unterstützen:

Mehrmethoden auf anderen Programmiersprachen über Erweiterungen:

,

Außenverbindungen

  • Forschungsarbeit darauf, wie man vielfache Absendung zu C ++ durch Bjarne Stroustrup, Yuriy Solodkyy und Peter Pirkelbauer sauber hinzufügt

HMS Monmouth / Allgemeines Lispeln-Gegenstand-System
Impressum & Datenschutz