DE69921474T2 - Methode-referenzierung in objektbasierter programmierung - Google Patents

Methode-referenzierung in objektbasierter programmierung Download PDF

Info

Publication number
DE69921474T2
DE69921474T2 DE69921474T DE69921474T DE69921474T2 DE 69921474 T2 DE69921474 T2 DE 69921474T2 DE 69921474 T DE69921474 T DE 69921474T DE 69921474 T DE69921474 T DE 69921474T DE 69921474 T2 DE69921474 T2 DE 69921474T2
Authority
DE
Germany
Prior art keywords
class
delegate
instance
computer
event
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Lifetime
Application number
DE69921474T
Other languages
English (en)
Other versions
DE69921474D1 (de
Inventor
H. Peter GOLDE
Anders Hejlsberg
W. Chad ROYAL
Tracy C. Sharpe
J. Michael TOUTONGHI
Edward H. Wayt
M. Scott WILTAMUTH
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Microsoft Corp
Original Assignee
Microsoft Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Microsoft Corp filed Critical Microsoft Corp
Publication of DE69921474D1 publication Critical patent/DE69921474D1/de
Application granted granted Critical
Publication of DE69921474T2 publication Critical patent/DE69921474T2/de
Anticipated expiration legal-status Critical
Expired - Lifetime legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/44Arrangements for executing specific programs
    • G06F9/448Execution paradigms, e.g. implementations of programming paradigms
    • G06F9/4488Object-oriented
    • G06F9/449Object-oriented method invocation or resolution

Landscapes

  • Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Stored Programmes (AREA)
  • Devices For Executing Special Programs (AREA)

Description

  • Technisches Gebiet der Erfindung
  • Diese Erfindung bezieht sich auf Computersprachen im Allgemeinen und insbesondere auf ein Verfahren und eine Vorrichtung zum Programmieren in objekt-basierten oder objekt-orientierten Sprachen.
  • Hintergrund der Erfindung
  • Höhere Programmiersprachen versetzten Entwickler in die Lage, einen Kode in kleinere Einheiten zu unterteilen. In nicht-objekt-orientierten Sprachen ist die kleinste Einheit der Unterteilung eine Prozedur oder Funktion. In objekt-orientierten Sprachen ist die kleinste Einheit der Unterteilung typischerweise eine Methode einer Klasse.
  • Viele moderne Programmiersprachen weisen ferner Mechanismen auf, die es Entwicklern ermöglichen, diese Unterteilungseinheiten wie Werte zu behandeln, die auch wie Werte verwendet werden können (übergeben, in Datenstrukturen gespeichert, etc.) und auch zum „Aufruf" einer Kodeeinheit, die der Wert repräsentiert, verwendet werden können. Verschiedene Sprachen stellen dabei verschiedene Mechanismen bereit.
  • In nicht-objekt-orientierten Programmiersprachen ist das am besten bekannte dieser Konstrukte der Funktionenzeiger, wie er in C und C++ gefunden wird. In funktionalen Programmiersprachen (LISP, ML, Scheme, etc.) ist diese Art der Programmierung üblich. In objekt-orientierten Programmiersprachen ist kein adäquater Mechanismus für diesen Zweck entwickelt worden.
  • Damit ein Programmiersystem (Sprache und Laufzeit) es Entwicklern ermöglicht, Methodenreferenzen zu erzeugen und zu verwenden, adressiert die vorliegende Erfindung folgende Designziele:
    • a) Definition einer Einheit, die die Gestalt der zu referenzierenden Methode definiert;
    • b) Erhalt einer Referenz auf eine Methode;
    • c) Speichern dieser Referenz in einer beliebigen Datenstruktur;
    • d) Übergeben der Referenz an einen von Dritten geschriebenen Kode;
    • e) Ermöglichung des Aufrufs der Methode durch jeden, der die Methodenreferenz besitzt; und
    • f) Ermöglichung der Bestimmung des Zielobjekt und der referenzierten Methode durch den Besitzer der Methodenreferenz.
  • Des Weiteren erreicht das Programmiersystem der vorliegenden Erfindung die oben genannten Ziele auf eine streng typisierte Art und Weise, die es ermöglicht für:
    • a) Entwickler, Probleme der Unverträglichkeit von Typen („type mismatch") früher (zur Kompilierzeit) denn später (zur Laufzeit) zu erkennen; und
    • b) Entwicklungswerkzeuge, dem Entwickler Informationen über die Gestalt von Komponenten, die Delegate verwenden, zu präsentieren.
  • Frühere Lösungen ähnlicher Problemstellungen
  • Eine Reihe von Produkten beinhalten C und C++ ähnliche Funktionenzeiger, wie z.B. Microsoft® Visual C++, Visual Basic und Visual Basic A, welche alle von der Microsoft Corporation erhältlich sind. Das Windows® API macht ebenfalls intensiven Gebrauch von Funktionenzeigern. Funktionenzeiger dieser Art sind aufgrund einer Reihe von Gründen nachteilig:
    • a) sie sind nicht typensicher („type safe") und resultieren in einer Typumwandlung („casting");
    • b) sie sind nicht sicherheitsbewusst – ein Funktionenzeiger ist lediglich ein Zeiger, der versehentlich geändert und dann aufgerufen werden kann, welches zu einem Absturz des Systems führt; und
    • c) sie erlauben es nicht das Zielobjekt und die Zielmethode aufzurufen.
  • Microsoft Java VM und ähnliche Produkte haben ein „Java Core Reflection"-System, welches eine primitive Form der Methodenreferenz aufweist. Ein Entwickler kann eine „java.lang.reflect.method" Instanz erhalten. Diese Form der Referenz ist inhärent spät-gebunden („late bound") und daher ineffizient.
  • Zusammenfassung der Erfindung
  • Einem Aspekt der vorliegenden Erfindung zufolge wird ein Computerprogrammprodukt gemäß Anspruch 1 vorgeschlagen.
  • Einem anderen Aspekt der vorliegenden Erfindung zufolge wird ein objektbasiertes Programmiersystem gemäß Anspruch 8 vorgeschlagen.
  • Einem weiteren Aspekt der vorliegenden Erfindung zufolge wird ein Verfahren zur Programmierung eines Computers gemäß Anspruch 19 vorgeschlagen.
  • Kurze Erläuterung der Zeichnungen
  • 1 zeigt ein Blockdiagramm der Hauptkomponenten der vorliegenden Erfindung.
  • 2 zeigt die für die vorliegende Erfindung passenden Plattformen und Träger.
  • 3 ist ein Beispiel J++ Computerprogramm gemäß der vorliegenden Erfindung.
  • 4 and 5A zeigen Beispieldeklarationen eines früh-gebundenen Delegaten gemäß der vorliegenden Erfindung.
  • 5B zeigt ein Beispiel der Konstruktion eines spät-gebundenen Delegaten basierend auf einem Methodennamen-String.
  • 6 zeigt eine Beispieldefinition der Klasse „Delegate" gemäß der vorliegenden Erfindung.
  • 7 ist eine Beispieldefinition der Klasse „MulticastDelegate".
  • 8 zeigt ein Ausführungsbeispiel, welches Microsoft® Visual J++ um die Einbeziehung einer „com.ms.lang.Callable" Schnittstelle erweitert.
  • 9 zeigt eine Beispiel-Ereignis(„Event")-Klasse gemäß der vorliegenden Erfindung.
  • 10 zeigt einen Beispiel-Ereignis-Handhabungs(„Event-Handling")-Kode gemäß der vorliegenden Erfindung.
  • 11 zeigt einen Beispiel-Ereignis-Handhabungs(„Event-Handling")-Kode gemäß der vorliegenden Erfindung.
  • 12 zeigt einen Beispiel-Ereignis-Handhabungs(„Event-Handling")-Kode gemäß der vorliegenden Erfindung.
  • 13 zeigt einen Beispiel-Ereignis-Handhabungs(„Event-Handling")-Kode gemäß der vorliegenden Erfindung.
  • 14A-14B zeigt ein Beispiel-Ereignis-Handhabungs(„Event-Handling")-Programm unter Verwendung von Delegaten gemäß der vorliegenden Erfindung.
  • 15A-15B zeigt ein Beispiel-Ereignis-Handhabungs(„Event-Handling")-Programm gemäß der vorliegenden Erfindung.
  • 16 zeigt ein Beispiel eines „single-cast event-handling"-Programms gemäß der vorliegenden Erfindung.
  • 17 zeigt eine Definition der Klasse „Event" gemäß der vorliegenden Erfindung.
  • 18 zeigt eine Beispieldefinition einer „event-handler"-Deklaration gemäß der vorliegenden Erfindung.
  • 19 zeigt eine Beispieldefinition einer „CancelEvent"-Klasse gemäß der vorliegenden Erfindung.
  • 20 zeigt eines Deklaration eines „event handlers" gemäß der vorliegenden Erfindung.
  • Detaillierte Beschreibung der Erfindung
  • In der folgenden detaillierten Beschreibung der bevorzugten Ausführungsformen wird auf die begleitenden Zeichnungen, die einen Teil hiervon bilden, Bezug genommen, in welchen spezifische Ausgestaltungen, in denen die Erfindung genutzt werden könnte, mittels Darstellungen gezeigt werden. Es ist verständlich, dass andere Ausgestaltungen benutzt und strukturelle Änderungen vorgenommen werden können, ohne den Rahmen der vorliegenden Erfindung zu verlassen.
  • EINFÜHRUNG
  • Die vorliegende Erfindung sieht einen Mechanismus, der im Folgenden „Delegat" (in den Ansprüchen „Delegierter", im Englischen „delegate") genannt wird, zur Referenz einer Methode in objekt-basierter Programmierung vor. Während ein Funktionenzeiger eine Referenz auf eine Funktion beinhaltet, beinhaltet ein Delegat eine Referenz auf eine Methode. Die beiden unterscheiden sich dadurch, dass der Funktionenzeiger nur eine Referenz (eine Funktion) beinhaltet, während der Delegat eine Referenz auf ein Objekt und eine Methode des Objekts beinhaltet.
  • Eine nützliche Eigenschaft eines hier beschriebenen Delegaten ist, dass der Delegat den Typ (Klasse) des Objekts, auf das es sich bezieht, nicht kennt oder sich nicht darum sorgt.
  • Alles was interessiert ist stattdessen, dass die Parameterliste der referenzierten Methode kompatibel mit dem Delegaten ist. Dies macht Delegaten sehr nützlich für anonyme Anwendungen der Benachrichtigung – ein Aufrufer, der den Delegaten aufruft, muss nicht genau wissen, welche Klasse oder welches Element aufgerufen wird.
  • Ähnlich einem Funktionenzeiger ist ein Delegat ein Wert. Wie andere Werte kann er Variablen zugewiesen, von einer Prozedur zu einer anderen übergeben werden etc.. Ein Delegat kann also verwendet/angewendet/aufgerufen werden. Kein oder mehrere Argumente können einem Delegaten während der Ausführung dieser Operation übergeben werden.
  • Delegate unterscheiden sich von Funktionenzeigern dadurch, dass Delegate sicher oder streng typisiert sein können. Des Weiteren, während Funktionenzeiger kontextfrei sind – wenn eine Funktion durch einen Funktionenzeiger aufgerufen wurde, hat die Funktion keinen Kontext außer dem, der durch Parameter hindurchgereicht wurde – trägt ein Delegat seinen Kontext mit sich. Wenn eine Methode durch einen Delegaten aufgerufen wird, findet der Aufruf auf das Objekt statt, auf dass sich der Delegat bezieht, und stellt so eine Methode mit einem bekannten Kontext zur Verfügung.
  • Wie ausführlicher weiter unten beschrieben werden wird, nimmt die Erfindung eine Reihe von verschiedenen Formen an, wie sie in 1 dargestellt sind. Wie darin gezeigt, ist das hier beschriebene Ausführungsbeispiel des Delegaten in Form einer Programmiersprache 10, eines Computerprogramms 12, eines Kompilierers („Compilers") 14, eines Java-Virtuelle-Maschinen-Interpretierers („Java Virtual Machine Interpreter") und eines Ereignismodells („event model") 18 ausgeführt. Wie in 2 gezeigt, können diese verschiedenen Ausgestaltungen auf einem Rechnersystem 20 ausgeführt werden (beinhaltend: konventionelle Rechenkomponenten, wie z. B., aber nicht darauf beschränkt, eine CPU, einem Speicher, einer Tastatur, einer Maus), wie beispielsweise auf, aber nicht darauf beschränkt, einem IBM-kompatiblen Personalcomputer, und gespeichert oder andersartig in maschinenlesbarer Form ausgestaltet werden, auf verschiedenen Trägermedien wie z.B. Festplatten 22, Floppy-Disketten 24, CD-ROM 26 oder als eine elektronischen Datenübertragung 28.
  • BEISPIELAUSGESTALTUNG DER ERFINDUNG IN J++
  • Das folgende Ausführungsbeispiel der Erfindung beschreibt eine Implementierung von Delegaten in Microsoft® Visual J++, Version 6.0, der Microsoft Corporation. Die vorliegende Erfindung ist jedoch in keinster Weise auf die J++Sprache beschränkt, sondern ist eher allgemeiner auf jedes objektorientiertes Programmiersystem, wie z. B. C++ oder einem objekt-basierten Programmiersystem wie Microsoft® Visual Basic, anwendbar. Die Formulierung „objekt-basiert" meint dabei eine Programmiersprache, in der Kode in Objekten organisiert werden, aber welche nicht notwendigerweise Vererbung („inheritance") unterstützen, wie Microsoft® Visual Basic.
  • Vor Beschreibung der Erfindung im Detail, wird ein einfaches Beispiel eines J++ Computerprogramms 30, welches Delegate verwendet, in 3 präsentiert, wobei eine Delegateninstanz eine Methode der Instanz kapselt. In diesem Fall, wird die Methode „Hallo" unter Verwendung eines Delegaten „f" aufgerufen. Ferner definiert die Deklaration des Delegaten die Arten der Methoden, die der Delegat in der Lage ist zu kapseln.
  • Das Beispielprogramm der 3 illustriert, wie eine Instanz f des Delegaten „SimpleDelegate" realisiert wird („f=new SimpleDelegate(o.hello)"), und im weiteren Verlauf aufgerufen wird („f.invoke()"). Wie ausführlicher weiter unten beschrieben werden wird, muss der Typ des Delegaten „SimpleDelegate" mit dem Typen der darauf verwiesenen Methode „hallo" übereinstimmen, um gültig und ausführbar zu sein. In diesem Fall benötigen sowohl „hallo" als auch „SimpleDelegate" keine Eingabeparameter und haben eine Ausgabe „void". Wie ebenfalls weiter unten erläutert werden wird macht dieses Erfordernis den Delegaten typensicher („type-safe").
  • Unten angeschlossen befindet sich eine Beschreibung von Delegaten, als eine Erweiterung der J++ Sprache, wie sie in Microsoft® Visual J++, Version 6.0 implementiert ist. Die Java-Sprachenspezifikation, wie sie von Sun Microsystems veröffentlicht wurde, wird hierin alternativ als „JLS" bezeichnet und wird ferner hierin teilweise zitiert.
  • Delegatendeklarationen im einem J++ Ausführungsbeispiel
  • Eine Delegatendeklaration gemäß dem folgenden Ausführungsbeispiel der Erfindung, spezifiziert eine neue Klasse, die entweder von „Delegate" oder „MulticastDelegate" abgeleitet wird. Die Delegatendeklaration („DelegateDeclaration") nimmt die Form an:
    DelegateModifiersoptdelegate ResultType Indentifier (FormalParameterListopt) Throwsopt
  • Die relevanten Produkte für Klassendeklarationen sind:
    ClassModifiersopt class Indentifier Superopt Interfacesopt ClassBody
  • Eine „DelegateDeclaration" resultiert in einer Klasse, die, wenn sie unter Verwendung der Java-Sprachensyntax des vorliegenden Beispiels deklariert wird, die folgenden Attribute aufweist:
    • 1) Für „ClassModifiersopt" weist die Klassendeklaration „DelegateModifiersopt" plus die folgenden zusätzlichen Modifikatoren auf, wobei angenommen wird, dass sie im gegebenen Kontext spezifiziert seien: „static", „final".
    • 2) Für „Indentifier"- hat den „Indentifier" der „DelegateDeclaration".
    • 3) Für „Superopt", es hat „extends com.ms.lang.MulticastDelegate", wenn der Multicast-Modifikator spezifiziert ist, und „extends com.ms.lang.Delegate", wenn der Multicast-Modifikator ausgelassen wurde.
    • 4) Für „Interfacesopt", es hat „".
  • Es folgt, dass, wenn ein Delegat in einem benannten Packet (s. §7.4.1 der JLS) mit vollständig qualifiziertem Namen P (siehe §6.7 der JLS) deklariert wurde, der Delegat dann den vollständig qualifizierten Name „P.Identifier" aufweist. Wenn der Delegat in einem unbenannten Packet (s. §7.4.2 der JLS) ist, dann weist der Delegat den vollständig qualifizierten Namen „Identifier" auf. Im Beispiel der 4 ist der Delegat „EmptyMethod" 32 in einer Kompilationseinheit ohne Packetangabe deklariert und daher ist „EmptyMethod" sein vollständig qualifizierter Name, wogegen im Beispielkode 34 der 5A der vollständig qualifizierte Name des Delegaten „EmptyMethod" „vista.EmptyMethod" lautet.
  • Im vorliegenden Ausführungsbeispiel, erzeugt der Kompilierer 14 (ausführbar auf einer digitalen Computerplattform) einen Kompilierzeitfehler:
    • 1) wenn der „Identifier", der einen Delegaten benennt, als Name irgendeines anderen Delegatentyps, eines Klassentyps oder eines Interfacetyps, deklariert im selben Packet (s. §7.6 der JLS), auftritt; oder
    • 2) wenn der „Identifier", der einen Delegaten benennt, auch als Typ durch eine „single-type-import" Deklaration (s. §7.5.1 der JLS) in der Kompiliereinheit (s. §7.3 der JLS), die die Delegatendeklaration enthält, deklariert ist.
  • Wirkungsbereich des Delegatentypennamens
  • Der „Identifier" in einer Delegatendeklaration spezifiziert den Namen des Delegaten.
  • Dieser Delegatenname hat als seinen Wirkungsbereich („scope", s. §6.3 der JLS) das gesamte Packet, in dem der Delegat deklariert ist.
  • Delegaten-Modifikatoren
  • Eine Delegatendeklaration kann Delegatenmodifikatoren beinhalten.
  • „DelegateModifiers" können Null oder eines der folgenden sein:
    public private static final multicast.
  • Wenn zwei oder mehrere Delegatenmodifikatoren in einer Delegatendeklaration auftreten, dann ist es üblich, aber nicht notwendig, dass sie in der Reihenfolge auftreten, die konsistent mit der oben bei der Produktion für „DelegateModifier" gezeigten Reihenfolge ist.
  • Eine Delegatendeklaration, die den multicast Modifikator beinhaltet, muss einen Ergebnistypen („ResultType)" von „void" haben; andernfalls tritt ein Kompilierfehler auf.
  • Der Zugriffsmodifikator „public" wird in §6.6 der JLS diskutiert. Der Kompilierer dieses Ausführungsbeispiels der Erfindung erzeugt einen Kompilierzeitfehler wenn:
    • 1) mehr als ein Delegatenmodifikator verwendet wird;
    • 2) wenn derselbe Modifikator mehr als einmal in einer Delegatendeklaration auftritt, oder wenn eine Delegatendeklaration mehr als einen der Zugriffsmodifikatoren „public" oder „private" aufweist; oder
    • 3) wenn der „private" Modifikator in einer Delegatendeklaration auftritt, die nicht in einer Klasse gekapselt ist.
  • Delegaten sind implizit „static". Es ist erlaubt, aber es wird streng als eine Frage des Stils davon abgeraten, den Modifikator „static" redundant innerhalb einer Delegatendeklaration zu spezifizieren. Ferner sind Delegaten implizit „final". Es ist erlaubt, aber es wird streng als eine Frage des Stils davon abgeraten, den Modifikator „final" redundant in einer Delegatendeklaration zu spezifizieren.
  • Gemäß dem vorliegenden Ausführungsbeispiel können Delegatendefinitionen dort auftreten, wo immer Klassendefinitionen auftreten. Wie Klassendefinitionen, kann eine Delegatendefinition in einer Klassendefinition gekapselt sein. Ferner sind Delegate immer auf oberster Ebene.
  • Die Elemente („Member") eines Delegaten beinhalten immer Elemente, die von der Basisklasse vererbt wurden (entweder „Delegate" – oder „MulticastDelegate"-Klasse), und zudem eine spezielle, automatisch erzeugte „invoke" Methode (beschrieben weiter unten) aufweisen, die zum Aufruf einer gekapselten Methode verwendet werden kann. Eine Delegatendeklaration resultiert weiter in einer Klasse mit einem speziellen, automatisch erzeugten Konstruktor.
  • Die Aufruf-Methode
  • Die Elemente eines Delegaten beinhalten eine automatisch erzeugte „invoke"-Methode, die zum Aufruf einer gekapselten Methoden verwendet werden kann. Die Signatur und der Ergebnistyp der „invoke"-Methode sind durch die Delegatendeklaration bestimmt. Insbesondere ist die Signatur der „invoke"-Methode:
    ResultType invoke (FormalParameterListopt) Throwsopt,
    wobei ResultType, FormalParameterListopt (so vorhanden) und Throwsopt (so vorhanden) diejenigen der Delegatendeklaration sind.
  • Delegateninstantiierung
  • Delegaten haben zwei Konstruktoren, und zwar:
    • 1) Einen „Instanz"-Konstruktor, dessen Form durch die „Delegate"-Basisklasse definiert ist. Die Argumente dieses Konstruktors, ein „Object" und ein „String" Methodenname spezifizieren kombiniert mit dem Typen des Delegaten ein Element des indizierten Objektes, das mit der Delegatendefinition übereinstimmt, eindeutig. Der neu konstruierte Delegat kapselt diese Methode.
    • 2) Einen speziellen „Methodendesignator"-Konstruktor, der die Methodenauflösung zur Kompilierzeit denn zur Ausführzeit ermöglicht. Der Methodendesignatordelegat ist nicht durch die „Java Core Reflection" dargelegt.
  • Die Klassen- und Instanzenkonstruktoren sind in keinster Weise besonders; sie werden im Detail in der Spezifikation der Basisklasse „Delegate" im Folgenden diskutiert. Ein Methodendesignatorausdruck wird zur Indizierung einer Klassen- oder einer Instanzmethode zum Zwecke der Delegateninstantiierung verwendet.
  • Die „ClassInstanceCreationExpression" nimmt folgende Form an:
    new ClassType (ArgumentListopt)
    DelegateInstantiationExpression
  • Die „DelegateInstantiationExpression" nimmt folgende Form an:
    new DelegateType(MethodDesignator)
  • Der „MethodDesignator" nimmt folgende Form an:
    MethodName
    Primary.Identifier
    super.Identifier
  • Der „DelegateType" ist eine Klasse, die sich von „com.ms.lang.Delegate" herleitet.
  • Ein Methodendesignator ist zur Designation einer Methode nicht ausreichend. Zur Benennung einer bestimmten Methode denn (möglicherweise) eines Satzes von Methoden ist es notwendig, sich auf den Ergebnistypen und die Signatur (Anzahl und Typen der Argumente) des Delegaten, der mit dem Methodendesignator realisiert wird, zu beziehen. Aus diesem Grunde werden der „MethodDesignator" und die neue Instanzspezifikationsform als eine Einheit beschrieben.
  • Delegateninstantiierung gebraucht Suchregeln, die denen der Methodenaufrufausdrücke (s. §15.11 der JLS) ähnlich sind. Eine Methode zu benennen ist aufgrund der Möglichkeit des Methodenüberladens und des Instanzmethodenüberschreibens komplex. Die Bestimmung der Methode, die durch einen Methodenaufrufausdruck aufgerufen werden wird, umfasst mehrere zusätzliche Schritte. Unten werden die Schritte, die in der Delegateninstantiierung, sowohl zur Kompilierzeit als auch zur Laufzeit, gemäß dem vorliegenden Ausführungsbeispiel der Erfindungen) involviert sind, beschrieben.
  • Früh-gebundene und spät-gebundene Delegate
  • Im Beispiel der 3 ist die Instantiierung („f=new SimpleDelegate(o.hello)") ein früh-gebundener („early-bound") Delegat, bei dem die Methode „hallo" zur Kompilierzeit bekannt ist. In einige Fällen ist die Methode, an die der Delegat gebunden sein sollte, während der Übersetzung nicht bekannt. Der Anwender einer interaktiven Entwicklungsumgebung könnte beispielsweise den Namen einer Methode zum Programmprototyping eingeben oder der Name der aufzurufenden Methode könnte auf irgendeine andere Art berechnet oder eingegeben werden. In diesem Falle kann die Instanz eines Delegaten durch Verwendung eines Zwei-Argumenten-Konstruktors gebildet werden.
  • Das erste Argument des Konstruktors spezifiziert das Objekt, in der die Methode aufgerufen werden soll. Das zweite Argument des Konstruktors spezifiziert den Namen der Methode. Das im ersten Argument spezifizierte Objekt wird überprüft, um sicherzustellen, dass es eine Methode des angegebenen Namens aufweist, mit derselben Signatur (d.h. Ergebnistyp und Argumenttyp) mit der die Delegatenklasse deklariert war. Wenn nein, tritt eine Ausnahme („exception") auf; wenn ja, wird ein neues Delegatenobjekt gebildet und zurückgegeben.
  • Die Instantiierung eines solchen „spät-gebundenen („late-bound") Delegaten, wie er unmittelbar zuvor beschrieben wurde, nimmt beispielsweise die Form „g=new SimpleDelegate(o,"hello")" an, wobei die Methode „hallo" ein String ist, der während der Ausführung des Programms definiert werden könnte. In diesem Fall des spät-gebunden Delegaten nimmt der Aufruf die Form „g.dynamicInvoke(Object⌷args)" an. Zur Verdeutlichung konstruiert das Beispielprogramm 36 der 5B einen spät-gebunden Delegaten auf einem String „Methodennamen".
  • Kompilierer-Ausführung
  • Wie oben dargelegt umfasst das Ausführungsbeispiel der vorliegenden Erfindung einen Kompilierer 14. Mehrere Schritte werden zur Ausführung eines Delegateninstantiiierungsausdrucks zur Kompilierzeit verlangt. Erstens muss der Kompilierer bestimmen, welche Klasse oder welche Schnittstelle („interface") zu durchsuchen ist. Zweitens muss der Kompilierer nach einer Methode suchen, die passend und verfügbar ist. Drittens muss der Kompilierer überprüfen, ob die Methode geeignet ist. Diese Prozesse werden im Folgenden im Detail beschrieben.
  • Kompilierzeit – Schritt 1: Bestimme die zu durchsuchende Klasse oder Schnittstelle:
  • Der erste Schritt zur Verarbeitung eines Delegateninstantiierungsausdrucks zur Kompilierzeit ist es den Namen der Methode herauszufinden und welche Klasse oder welches Interface auf Definitionen von Methoden dieses Namens zu überprüfen ist. Es gilt mehrere Fälle zu berücksichtigen, welche von der Gestalt des Methodendesignators abhängen:
    • 1) Wenn die Ausgestaltung „MethodName" ist, dann gibt es zwei Unterfälle:
    • a) Wenn es ein einfacher Name ist, das heißt nur ein „Identifier", dann ist der Name der Methode der „Identifier" und die zu durchsuchende Klasse oder die Schnittstelle ist diejenige, deren Deklaration den Methodendesignator enthält.
    • b) In allen anderen Fällen hat der qualifizierte Name die Ausgestaltung „FieldName.Identifier"; dann ist der Name der Methode der „Identifier" und die zu durchsuchende Klasse oder das Interface ist der deklarierte Typ des Feldes, bezeichnet mit „FieldName".
    • 2) Wenn die Ausgestaltung „Primary.Identifier" ist, ist der Name der Methode der „Identifier" und die zu durchsuchende Klasse oder das Interface ist der Typ des „Primary"-Ausdrucks.
    • 3) Wenn die Form „super.Identifier" ist, dann ist der Name der Methode der „Identifier" und die zu durchsuchende Klasse ist die Oberklasse der Klasse, deren Deklaration die Delegateninstantiierung enthält. Ein Kompilierzeitfehler tritt auf, wenn solch ein Methodendesignator in einem Interface oder in der Klasse „Object" oder in einer statischen („static") Methode, einem statischen („static") Initialisierer oder einem Initialisierer für eine statische („static") Variable erscheint. Es folgt, dass ein Methodendesignator dieser Art nur in einer Klasse verschieden der Klasse „Object" erscheinen kann, und zwar nur im Hauptteil einer Instanzmethode, im Hauptteil eines Konstruktors oder eines Initialisierers für eine Instanzvariable.
  • Kompilierzeit – Schritt 2: Bestimme Methodensignatur:
  • Der zweite Schritt durchsucht die Klasse oder das Interface des vorangegangenen Schrittes nach Methodendeklarationen. Dieser Schritt verwendet den Namen der angegebenen Methode und die Typen der formalen Parameter der Delegatendefinition zur Bestimmung von Methodendeklarationen, die sowohl passend als auch verfügbar sind, d.h. Deklarationen, die mit dem Typ des Delegaten, der instanziiert wird, übereinstimmen, und die korrekt aus dem Delegateninstantiierungsausdruck aufgerufen werden können. Da die Übereinstimmungsregeln strikt sind, kann es nur eine solche Methodendeklaration geben.
  • Eine Methode stimmt entweder mit dem Delegatentyp überein oder nicht. Es ist möglich, eine Delegateninstanz des Typs T, die die Methode M kapselt zu instanziieren, wenn und nur wenn M mit T übereinstimmt.
  • Sei M die Methode and T der Typ des Delegaten. M entspricht T wenn und nur wenn alles des Folgenden zutrifft:
    • 1) M und T haben die gleiche Anzahl von formalen Parametern;
    • 2) Der Typ jedes der Parameter von M entspricht identisch den Typen der Parameter von T;
    • 3) Der Ergebnistyp von M entspricht identisch dem Ergebnistyp von T; und
    • 4) M ist nicht zum Auswerfen von mehr Ausnahmen als T deklariert. Wenn M eine „throws" Klausel aufweist, die irgendwelche überprüften Ausnahmetypen aufführt, dann muss T ebenso eine „throws" Klausel aufweisen und für jede der überprüften Ausnahmetypen, die in der „throws" Klausel von M aufgeführt ist, muss die gleiche Ausnahmeklasse oder eine ihrer Oberklassen in der „throws" Klausel von T vorkommen.
  • Es ist zu beachten, dass, da die Übereinstimmungsregeln striktes Übereinstimmen (identische Typen für Parameterlisten und Ergebnistypen) erfordern, es im besten Falle genau eine übereinstimmende Methode für jedes gegebene Ziel gibt.
  • Die Klasse oder das Interface, das durch den hierin beschriebenen Prozess beschrieben wird, wird nach einer Methodendeklaration durchsucht, die dem Delegatentyp entspricht; Methodendefinitionen, vererbt von Oberklassen und Oberschnittstellen werden in diese Suche eingebunden. Ob eine Methodendeklaration verfügbar für einen Methodenaufruf ist, hängt von dem Zugriffmodifikator („public", „none", „protected" oder „private") in der Methodendeklaration ab und davon, wo der Methodendesignator erscheint. Wenn die Klasse oder das Interface keine Methodendeklaration aufweist, die sowohl passend als auch verfügbar ist, dann wird ein Kompilierzeitfehler erzeugt.
  • Kompilierzeit – Schritt 3: Ist die gewählte Methode geeignet?
  • Wenn es eine passende und verfügbare Methodendeklaration für einen Delegateninstantiierungsausdruck gibt, wird diese die Kompilierzeitdeklaration („compile-time declaration") für den Delegateninstantiierungsausdruck genannt. Mehrere weitere Überprüfungen der Kompilierzeitdeklaration müssen vorgenommen werden. Ein Kompilierzeitfehler wird erzeugt, wenn:
    • 1) Der Methodendesignator einen MethodenNamen der Ausbildung „Identifier" aufweist und der Methodendesignator innerhalb einer „static" Methode, einem „static" Initialisierer oder einem Initialisierer für eine „static" Variable auftritt.
    • 2) Wenn der Methodendesignator einen MethodenNamen der Form „TypeName.Identifier" aufweist.
  • Die folgende Kompilierzeitinformation wird dann mit dem Methodenaufruf zur Verwendung während der Laufzeit verknüpft:
    • 1) Eine Referenz auf die Kompilierzeitdeklaration (die Methode).
    • 2) Die Klasse oder das Interface, dass die Kompilierzeitdeklaration beinhaltet (das Ziel).
    • 3) Der Aufrufmodus, der wie folgt berechnet wird:
    • a. Wenn die Kompilierzeitdeklaration den „private" Modifikator aufweist, dann ist der Aufrufmodus „nonvirtual".
    • b. Andernfalls, wenn der Teil des Methodenaufrufs vor der linken Klammer in der Gestalt „super.Identifier" vorliegt, denn ist der Aufrufmodus „super".
    • c. Andernfalls, wenn die Kompilierzeit-Deklaration in einem Interface auftritt, denn ist der Aufrufmudus „interface".
    • d. Sonst ist der Aufrufmodus „virtual".
  • Laufzeit-Ausführung
  • Die vorliegende Erfindung legt weiter eine Java-Virtuelle-Maschinen-Übersetzersoftware (1) zur Implementierung von Delegaten der vorliegenden Erfindung vor.
  • Mehrere Schritte sind erforderlich, um einen Delegateninstantiierungsausdruck während der Laufzeit auszuführen. Zunächst muss der Kompilierer die Verfügbarkeit des Zieltyps und der Zielmethode bestimmen. Zweitens muss der Kompilierer die aufzurufende Methode ausfindig machen, wobei die Möglichkeit des Überschreibens der Instanzmethode zu berücksichtigen ist.
  • Laufzeit – Schritt Nr. 1: Überprüfe Zugänglichkeit von Typ und Methode:
  • Sei C die den Delegateninstantiierungsausdruck enthaltende Klasse und sei T die Klasse oder das Interface, dass die Kompilierzeitdeklaration für den Delegateninstantiierungsausdruck enthält und m sei der Name der Methode, wie er zur Kompilierzeit bestimmt wurde.
  • Die Java-Virtuelle-Maschinen-Übersetzersoftware 16 stellt sicher, als Teil einer Verbindung („linkage"), dass die Methode m immer noch im Typ T existiert. Wenn dies nicht wahr ist, wird eine „IllegalArgumentException" (welche eine Unterklasse der Laufzeitausnahme „RuntimeExecption" ist) erzeugt. Wenn der Aufrufmodus „interface" ist, dann muss die Virtuelle-Maschinen-Software 16 auch überprüfen, ob der Zielreferenztyp immer noch das spezifizierte Interface implementiert. Implementiert der Zielreferenztyp nicht mehr das Interface, dann wird ein „IncompatibleClassChangeError" erzeugt.
  • Die Virtuelle-Maschinen-Software 16 muss ferner sicherstellen, dass während der Verbindung der Typ T und die Methode m verfügbar sind.
  • Für den Typen T:
    • 1) Wenn T im gleichen Packet wie C ist, dann ist T verfügbar.
    • 2) Wenn T in einem anderen Packet als C ist und T ist „public", dann ist T verfügbar.
  • Für die Methode m:
    • 1) Wenn m „public" ist, dann ist m verfügbar. (Alle Elemente von Schnittstellen sind „public" (s. §9.2 der JLS)).
    • 2) Wenn m „protected" ist, dann ist m verfügbar, wenn und nur wenn entweder T im selben Packet wie C ist oder C ist T oder eine Unterklasse von T.
    • 3) Wenn m den vorgegebenen (Packet-)Zugang aufweist, dann ist m verfügbar wenn und nur wenn T im selben Packet wie C ist.
    • 4) Wenn m „public" ist, dann ist m verfügbar wenn und nur wenn C T ist.
  • Wenn weder T noch m verfügbar sind, dann wird eine „IllegalAcessException" produziert (s. §12.3 der JLS).
  • Laufzeit – Schritt Nr. 2: Lokalisiere die aufzurufende Methode:
  • Die Strategie für die Methodensuche hängt von dem Aufrufmodus ab. Im vorliegenden Ausführungsbeispiel ist es nicht möglich, eine statische Methode mit einem Delegaten zukapseln, und daher ist es klar, dass eine Instanzmethode von dem Delegaten gekapselt werden muss und dass es eine Zielreferenz gibt. Wenn die Zielreferenz null ist, wird zu diesem Zeitpunkt eine „NullPointerExeception" geworfen. Ansonsten soll die Zielreferenz sich auf das Zielobjekt beziehen und wird als Wert des Schlüsselwortes this, wenn der Delegat aufgerufen wird, verwendet. Die anderen vier Möglichkeiten des Aufrufmodus werden als nächstes von der Java-Virtuelle-Maschinen-Übersetzersoftware 16 berücksichtigt, und zwar wie folgt.
  • Wenn der Aufrufmodus „nonvirtual" ist, ist ein Überschreiben nicht erlaubt.
  • Methode m der Klasse T ist diejenige, die aufgerufen wird. Sonst ist der Aufrufmodus „interface", „virtual" oder „super" und Überschreiben kann vorkommen. Eine dynamischer Methodennachschlag wird verwendet. Der dynamische Methodensuchprozess startet von Klasse S, die wie folgt festgelegt wird:
    • 1) Wenn der Aufrufmodus „interface" oder „virtual" ist, dann ist S anfangs die aktuelle Laufzeitklasse R des Zielobjekts. Wenn das Zielobjekt ein Feld ist, ist R die Klasse des Objektes. (Beachte, dass für den Aufrufmodus „interface", R notwendigerweise T implementiert; für den Aufrufmodus „virtual", ist R notwendigerweise entweder T oder eine Unterklasse von T)
    • 2) Wenn der Aufrufmodus „super" ist, dann ist S anfangs die Oberklasse der Klasse C, die die Delegateninstantiierung enthält.
  • Die dynamische Methodensuche verwendet folgende Prozedur, um Klasse S und dann die Oberklasse von Klasse S, wenn benötigt, nach Methode m zu durchsuchen:
    • 1) Wenn Klasse S eine Deklaration einer Methode mit Namen m mit demselben Deskriptor (gleiche Anzahl von Parametern, die gleichen Parametertypen, und den gleichen Rückgabetypen) wie vom Methodenaufruf zur Kompilierzeit bestimmt (wie oben beschrieben) enthält, dann ist dies die Methode die vom Delegaten gekapselt werden soll, und die Prozedur terminiert.
    • 2) Sonst, wenn S nicht T ist, wird die gleiche Nachschlagprozedur unter Verwendung der Oberklasse von S ausgeführt; was immer herauskommt ist das Ergebnis der Suche.
  • Diese Prozedur wird eine brauchbare Methoden gefunden haben, wenn es die Klasse T erreicht, da ansonsten eine „IllegalAccessException" durch die oben beschriebenen Überprüfungen geworfen worden wäre. Es wird vermerkt, dass der Suchprozess, während er hier explizit beschrieben wurde, oftmals implizit implementiert sein wird.
  • Laufzeit – Schritt Nr. 3: Sicherheitsüberprüfung:
  • Das hier beschriebene Ausführungsbeispiel von Delegaten weist Prozeduren zur Sicherstellung dessen auf, dass Delegaten nicht verwendet werden, um vertrauenswürdigen Kode zu untergraben. Ohne spezielle Sicherheitsvorkehrungen können vertrauensunwürdige Methoden Delegate potentiell so verwenden, dass vertrauenswürdige Methoden auf solche Art aufgerufen werden, dass keine vertrauensunwürdige Klasse im Aufrufstapelspeicher erscheint. Bei normaler Java-Sicherheit würde die vertrauenswürdige Methode erfolgreich sein, wenn keine vertrauensunwürdige Methode im Aufrufstapelspeicher wäre. Sie würde potentiell fehlschlagen, wenn die originale vertrauensunwürdige Methode im Aufrufstapelspeicher wäre. Ein gutes Beispiel ist die Methode „ java.io.File.delete"; wenn ein vertrauensunwürdiger Kode die Methode aufrufen würde, würde eine SicherheitsAusnahme („SecurityException") geworfen werden. Wenn jedoch ein vertrauensunwürdiger Kode diese vertrauenswürdige Methode in einem Delegaten kapseln und einem vollständig vertrauenswürdigen Kode, der dann den Delegaten aufrufen würde, übergeben würde, würde die Methode (java.io.File.delegate) gelingen. Infolgedessen führt das hier beschriebene Ausführungsbeispiel eine spezielle Sicherheitsüberprüfung bei Instantiierung des Delegaten durch, wie im Folgenden ausgeführt wird. Diese Sicherheitsüberprüfung wird während der Laufzeit durchgeführt.
  • Das hier beschriebene Ausführungsbeispiel der Erfindung erweitert das Standard-Java-Sicherheitsmodell um die Zuordnung einer Menge von Sicherheitspermissions für jede Javaklasse. Für eine gegebene Klasse bestimmt der zugeordnete Satz von Sicherheitspermissions die vertrauenswürdigen Operationen (wie z. B. Datei-Input-Output und Drucken), die die Methoden erlaubt sind auszuführen. Vertrauensunwürdige Klassen weisen einen leeren Satz von Sicherheitspermissions auf, während voll vertrauenswürdige Klassen einen vollständigen Satz von Sicherheitspermissions aufweisen (d.h. sie weisen jede Permission auf).
  • Um als Delegateninstantiierung während der Laufzeit erfolgreich zu sein, müssen die Permissions von C (der Klasse, die die Delegateninstantiierung beinhaltet) eine Obermenge der Permissions, die von der m beinhaltenden Klasse besessen werden, sein, was während der Laufzeit bestimmt wird. Wenn dies nicht der Fall ist, wird eine „IllegalAccessException" geworfen. Ferner erfordert die Sicherheitsüberprüfung, dass Klassen, die von einem Delegaten oder einer Multidelegatenklasse herrühren „final" sind, was eine Suche in der Aufrufkette zum Erkennen der Einheit, welche den Delegaten erzeugt, erlaubt. Eine direkte Konsequenz ist es, dass vertrauensunwürdige Klassen nur Delegate auf vertrauensunwürdige Methoden erzeugen können, während vollständig vertrauenswürdige Klassen (d.h. Systemklassen) Delegaten auf jede verfügbare Methode erzeugen können.
  • Kompilierer- gegen Interpretiereraktivitäten
  • Wie oben beschrieben sind die Kompilierer- 14 und Interpretierersoftware 16 separate Softwarekomponenten. Jedoch können diese Komponenten in einigen Fällen die gleichen Funktionen ausführen, wie das Einbinden von Delegaten, abhängig von dem Modus der Operation. Ferner können die Funktionen der Kompilierer- 14 und der Interpretierersoftware 16 in einigen Fällen ausgetauscht oder miteinander geteilt werden. Demzufolge ist die Erfindung in keinster Weise auf die hier beschriebene bestimmte Unterteilung von Funktionen im Ausführungsbeispiel beschränkt. Die Kompilierer- 14 und Interpretierersoftware 16 sollte man sich eher so vorstellen, als teilten sie die gemeinsame Aufgabe der Ausführung objekt-basierten Computerkodes zur Vorbereitung seiner Ausführung von einem Computer.
  • Die Klasse „com.ms.lang.Delegate"
  • Wie oben ausgeführt rühren alle Delegaten von dieser Basisklasse „Delegate" her. Ein Objekttyp „Delegate" kapselt eine aufrufbare Einheit: Eine Instanz und eine Methode einer Instanz. Eine Beispieldefinition 38 der Klasse „Delegate" ist in 6 gezeigt.
  • Der „protected Delegate(Object target, String methodName)"-Konstruktor initialisiert ein neu erzeugtes „Delegate"-Objekt so, dass es das durch Argumente spezifizierte Ziel und die Methode kapselt. Wenn „target" Null ist, wird eine „NullPointerException"-Ausnahme ausgegeben. Das „methodName"-Argument muss eine Methode bestimmen, die passend, verfügbar und geeignet, wie oben definiert, ist. Wenn keine übereinstimmende Zielmethode gefunden werden kann, wird eine „IllegalArgumentException"-Ausnahme zur Laufzeit geworfen. Wenn eine Methode nicht gefunden werden kann, wird ein „NoSuchMethodError" geworfen.
  • Das Ergebnis von „public final boolean equals (Object obj)" ist „true", wenn und nur wenn das Argument nicht „null" und ein „Delegate"-Objekt ist, dass die gleiche Zielmethode und Aufrufliste wie dieses Delegatenobjekt aufweist. Es ist zu beachten, dass zwei Delegaten nicht vom selben Typ sein müssen, um sich zu entsprechen, wie unter „Delegate.equals" definiert. Dieser Ausdruck überschreibt die „equals"-Methode des Objekts (s. §20.1.3 der JLS).
  • Der „Ausdruck public static final Delegate combine(Delegate a, Delegate b)" kombiniert die beiden gegebenen Delegate zur Ausbildung eines einzigen Delegaten. Wenn sowohl a als auch b Null sind, ist auch das Ergebnis Null. Wenn entweder a oder b Null sind, ist das Ergebnis der Delegat, der nicht Null ist. Wenn weder a noch b Null sind, ist das Ergebnis ein neuer Delegat mit einer neuen Aufrufliste, die aus der Aneinanderhängung der Aufruflisten von a und b, in dieser Reihenfolge, gebildet wird. Es wird nicht als Fehler angesehen, wenn die Aufrufliste doppelte Einträge – ein Eintrag, der auf dieselbe Methode auf dasselbe Objekt verweist – aufweist. Wenn weder a noch b Null sind, dann müssen die Delegaten von gleichem tatsächlichem Typ sein. Ansonsten wird die Ausnahme „IllegalArgumentException" vom Kompilierer 14 geworfen. Wenn weder a noch b Null sind, dann müssen die Delegaten a und b von einem tatsächlichen Typ sein, der von der Klasse „MulticastDelegate" abstammt. Andernfalls wird die Ausnahme „MulticastNotSupportedException" vom Kompilierer 14 geworfen.
  • Der Ausdruck „public static final Delegate combine(Delegate⌷delegates)" gibt einen Delegaten mit einer Aufrufliste zurück, die aus der Aneinanderhängung der Aufruflisten von jedem der Delegaten im Delegatenfeld, in Reihenfolge, gebildet wird. Ist die resultierende Aufrufliste leer, ist das Ergebnis Null. Das Delegatenfeld kann Einträge von Null aufweisen; solche Einträge werden ignoriert. Wenn der Delegatenfeldparameter Null oder leer ist, ist das Ergebnis Null. Die Elemente des Delegatenfeldes, die nicht Null sind, müssen vom selben tatsächlichen Typ sein; ansonsten wird eine Ausnahme „IllegalArgumentException" geworfen. Existieren mehrere Elemente im Delegatenfeld, die nicht Null sind, dann müssen diese Elemente von einem tatsächlichen Typus sein, der aus der Klasse „MulticastDelegate" stammt. Ansonsten wird eine „MulticastNotSupportedException"-Ausnahme vom Kompilierer 14 geworfen.
  • Der Ausdruck „public static final Delegate remove(Delegate source, Delegate value)" gibt einen Delegaten mit einer Aufrufliste zurück, die durch Löschen des letzten Auftretens (wenn vorhanden) des durch den Wertparameter gegebenen Delegaten aus der Aufrufliste des durch den Quellenparameter bestimmten Delegaten gebildet wird. Der Delegat, der von der Aufrufliste herausgenommen wird, ist der letzte Delegat, für den der folgende Ausdruck wahr ist: "value.equals(delegate)", wobei Delegat das in Frage kommende Aufruflistenelement ist. Wenn der Wertparameter Null oder wenn der durch den Wertparameter gegebene Delegat nicht in der Aufrufliste der Quelle erscheint, ist das Ergebnis der Quellenparameter. Wenn die resultierende Aufrufliste leer ist, ist das Ergebnis Null. Wenn der Quellenparameter Null ist, ist das Ergebnis Null.
  • Der Befehl „public final Object dynamicInvoke(Object⌷args)" kann zum Aufruf der Methode in spät-gebundener Art verwendet werden („Delegate.dynamicInvoke"). Bei Aufruf löst das „dynamicInvoke"-Element die Ausführung der Methode aus, die der Delegat gekapselt aufweist, wobei die Elemente der „args"-Argumente als Argumente an die Methode übergeben werden. Das Ergebnis von „dynamicInvoke" ist das Ergebnis des Aufrufs der gekapselten Methode. Wenn das Ergebnis des Methodenaufrufs eine Objektreferenz ist, wird diese Referenz zurückgegeben. Im anderen Falle, wenn das Ergebnis ein primitiver Wert ist, dann wird der primitive Wert in ein Objekt gehüllt und zurückgegeben (z.B. ein boolescher Wert wird in ein boolesches Objekt gehüllt). Im anderen Falle ist der Rückgabetyp der Methode „void", und ein den „null"-Wert enthaltendes Objekt wird zurückgegeben.
  • Die „public final static Method getMethod ()"-Methode gibt eine Referenz auf ein eindeutiges Methodenobjekt zurück, dass die Methode des (Ziel, Methoden)-Paares ist.
  • Die „public final static Object getTarget ()"-Methode gibt eine Referenz auf die Instanz des Teils des (Instanz, Methoden)-Tupels zurück, das zur Kapselung einer aufrufbaren Einheit notwendig ist.
  • Die „public Delegate⌷getInvocationList ()"-Methode gibt die Aufrufliste dieses Delegaten zurück, in Aufrufreihenfolge. Für Nicht-Multicast-Delegate ist das Ergebnis immer ein Feld mit einem einzigen Element. Für Multicast-Delegate, wie unten beschrieben, kann das resultierende Feld mehr als ein Element aufweisen. Bei der Aufrufliste jedes der Elemente im zurückgegebenen Feld ist sichergestellt, dass sie genau einen Eintrag aufweist.
  • Multicast-Delegate
  • Alle Multicast-Delegate rühren aus der Klasse „MulticastDelegate" her, in diesem Java-Ausführungsbeispiel bezeichnet als „com.ms.lang.MulticastDelegate". Der Effekt des Aufrufens eines Multicast-Delegaten könnte sein, dass mehrere Methoden aufgerufen werden. Die Menge der Methoden, die durch die „invoke"-Methode des Delegaten aufgerufen werden, wird als die Aufrufliste des Delegaten bezeichnet, und diese kann durch Benutzung der „getInvocationList"-Methode erhalten werden.
  • Ein Delegat, der direkt von „Delegate" abstammt, wird immer eine Aufrufliste mit einem Element aufweisen – sich selbst. Ein Delegat, der direkt von der „MulticastDelegate"-Klasse abstammt, kann eine Aufrufliste mit mehr als einem Element aufweisen. Die Methoden „Delegate.combine" und „Delegate.remove" werden zur Erzeugung neuer Aufruflisten verwendet.
  • Die „invoke"- und „dynamicInvoke"-Methoden rufen als Gruppe jeden der Delegaten in der Aufrufliste durch Aufruf mit der übergebenen Argumentenliste auf. Die Delegaten werden synchron aufgerufen, in der Reihenfolge, in welcher sie in der Aufrufliste auftreten. Wenn einer der Delegaten eine Ausnahme zurückgibt, dann wird der Multicast beendet und die Ausnahme zum Verwender der Aufrufmethode weitergeleitet. Während ein Multicast im Fortgang ist, können Aufrufe zu „Delegate.combine" und „Delegate.remove" auftreten. Solche Aufrufe berühren die durch den bereits fortschreitenden Multicast verwendete Aufrufliste nicht.
  • Im vorliegenden Ausführungsbeispiel der Erfindung ist die Klasse „MulticastDelegate" 40, wie in 7 dargestellt, definiert.
  • Der Ausdruck „protected MulticastDelegate next" stellt eine interne Referenz auf den nächsten Delegaten in der Multicast-Kette dar. Damit eine korrekte Aufrufsequenz erhalten bleibt, muss der nächste Delegat aufgerufen werden bevor die Methode aufgerufen wird, die dieser Delegat kapselt.
  • Der „protected MulticastDelegate(Object target, String methodName)" Konstruktor arbeitet wie die korrespondierenden Konstruktoren, die in der „Delegate"-Basisklasse definiert sind.
  • Ein alternatives Ausführungsbeispiel des Aufrufs eines Multicast-Delegaten ist es, ein Feld von Delegaten aufzubauen, welche durch Durchlaufen der jeweils „nächsten" Kette des Multicast-Delegaten aufzurufen sind. Diese Liste könnte auf dem Stapelspeicher des Programms platziert werden. Die Virtuelle-Maschinen-Interpretiersoftware 16 durchschreitet dann dieses Feld in umgekehrter Reihenfolge und ruft die Aufrufmethode jedes Delegaten mit den Parametern auf, die der Multicast-Delegaten-Aufruf-Methode übergeben wurden. Der Vorteil dieser Technik ist es, dass der Programmstapelspeicher nicht so tief sein muss, da sich maximal nur zwei Kopien der Parameter, die an die Aufruf-Methode des Multicast-Delegaten übergeben werden, auf dem Stapelspeicher befinden.
  • Weiteres Ausführungsbeispiel: Einhüllen („wrapping") statischer Elemente
  • In einem alternativen Ausführungsbeispiel der Erfindung, ist die J++ Sprache zusätzlich um das Einhüllen von statischen Elementen einer Klasse erweitert. Für diesen Zweck ist ein „Klassen"-Konstruktor, dessen Gestalt durch die „Delegate"-Basisklasse definiert ist, vorgesehen. Die Argumente für diesen Konstruktor, eine Klasse und ein String-Methodenname, kombiniert mit dem Typen des Delegaten, spezifiziert ein statisches Element der angegebenen Klasse, die der Delegatendefinition entspricht. Der neu konstruierte Delegat kapselt die statische Methode ein. Dieser Konstruktor nimmt die folgende Gestalt an:
    protected Delegate(Class class, Sting methodName)
  • Dieser Konstruktor initiiert ein neu erzeugtes Delegatenobjekt so, dass es die durch die Argumente spezifizierte statische Methode kapselt. Wenn die Klasse Null ist, wird eine „NullPointerException"-Ausnahme ausgelöst. Das „methodName"-Argument muss eine Methode benennen, die passend, verfügbar und geeignet ist, wie oben definiert. Wenn keine entsprechende Zielmethode gefunden werden kann, wird eine Ausnahme „IllegalArgumentException" zur Laufzeit geworfen. Wenn gar keine solche Methode gefunden wird, wird eine „IllegalArgumentException" geworfen.
  • Im ersten Schritt zur Kompilierzeit muss für Delegate, die statische Elemente einhüllen, die zu durchsuchende Klasse oder das Interface bestimmt werden. Wenn es sich um einen qualifizierten Namen der Form „TypeName.Identifier" handelt, dann ist der Name der Methode der „Identifier" und die zu durchsuchende Klasse ist diejenige mit dem Namen „TypeName". Wenn „TypeName" der Name eines Interfaces denn einer Klasse ist, tritt ein Kompilierzeitfehler auf, weil diese Form nur statische Methoden benennen kann und Interfaces keine statische Methoden aufweisen. Es ist auch notwendig, wie im Falle des Einhüllens von Instanzenelementen einer Klasse, zu bestimmen, ob die Methode geeignet ist. Wenn es eine passende und verfügbare Methodendeklaration für einen Delegateninstantiierungsausdruck gibt, wird er die Kompilierzeit-Deklaration für den Delegateninstantiierungsausdruck genannt.
  • Weitere Überprüfungen müssen auf die Kompilierzeit-Deklaration vorgenommen werden. Wenn der Methodendesignator einen MethodenNamen der Form „Identifier" aufweist, und der Methodendesignator in einer statistischen Methode oder in einem statischen Initialisierer oder in einem Initialisierer für eine statische Variable auftritt, tritt ein Kompilierzeitfehler auf. Ansonsten ist das Einhüllen von statischen Elementen eine Erweiterung oder Modifikation zum oben beschriebenen Einhüllen von Instanzenelementen.
  • Gemäß diesem alternativen Ausführungsbeispiel ist ein entsprechender Konstruktor auch für die Multicast-Delegaten-Klasse vorgesehen:
    protected MulticastDelegate(Class class, String methodName).
  • Dieser Konstruktor arbeitet wie der entsprechende, in der „Delegate"-Basisklasse definierte Konstruktor.
  • Aufrufbare Schnittstellen
  • Microsoft® Visual J++ unterstützt vielfache Vererbung nicht. Jedoch wird manchmal eine solche Schnittstelle nötig sein, um den existierenden Kode auf einen Delegatentypen zu konvertieren. Diese Situation kann zu „java.lang.Thread" gegen „java.lang.Runnable" analogisiert werden. Um dieses Problem anzugehen, erweitert ein Ausführungsbeispiel der Erfindung Microsoft® Visual J++ um die Einbeziehung einer „com.ms.lang.Callable" Schnittstelle 42, wie sie in 8 gezeigt wird. Bevorzugterweise implementieren Delegaten diese Schnittstelle.
  • DELEGATENBASIERTES EREIGNISMODELL
  • Im objekt-orientierten Programmieren ist eine Ereignis („Event") ein Konstrukt, welches einer Ereignisquelle („event source") ermöglicht, einen Ereignis-Listener (oder einer Menge von Ereignis-Listenern) anonym zu unterrichten, dass ein Zustandsübergang irgendeiner Art erfolgt ist. Ereignisse werden typischerweise in einem größeren „Komponentenmodell" genannten System verwendet, das beschreibt, wie eine Komponente ihren Funktionalitätskode, der die Komponente verwendet, zur Verfügung stellt. Auf niedrigster Ebene beschreiben die meisten modernen Komponentenmodelle, wie eine Komponente ihre Eigenschaften (die den Zustand der Komponente beschreiben), ihre Methoden (die Aktionen zur Verfügung stellen, die die Komponente in der Lage ist auszuführen) und Ereignisse (Benachrichtigungen der Komponente, dass etwas interessantes passiert ist) zur Verfügung stellt.
  • Ein Ereignisaufruf ist wie ein rückwärtiger Methodenaufruf. Bei einem Methodenaufruf ruft ein Komponentenkonsument eine Methode der Komponente auf, eine Anzahl von Argumenten übergebend. Bei einem Ereignis erfolgt der Aufruf in umgekehrter Reihenfolge – die Komponente ruft eine vom Komponentenkonsumenten zur Verfügung gestellte Methode auf, eine Anzahl von Argumenten übergebend. Neben dem Unterschied in der Richtung des Aufruf gibt es noch einige andere hervorstechende Unterschiede.
  • Bei einem Methodenaufruf weist der Konsument typischerweise eine explizite Abhängigkeit von der Komponente, die aufgerufen wird, auf. Ereignisaufrufe sind dagegen typischerweise anonym – die Komponente weist keine explizite Abhängigkeit vom Komponentenkonsument auf. Stattdessen können Listener sich mit einem Ereignis oder einer Menge von Ereignissen unter Verwendung eines Mechanismus, der von der Ereignisquelle zur Verfügung gestellt wird, verbinden.
  • Ferner bestimmt bei einem Methodenaufruf der Angerufene die Gestalt der Methode – die Anzahl und Typen von Argumenten und den Rückgabetyp. Bei einem Ereignisaufruf bestimmt die Ereignisquelle (der Aufrufende) die Gestalt.
  • Im Ausführungsbeispiel des delegaten-basierten Komponentenmodells gemäß der vorliegenden Erfindung wie unten ausgeführt werden Ereignisse typischerweise zur Kommunikation zwischen einer Komponente (oftmals von einen kommerziellen Anbieter geschrieben) und einem Ereignishandhabungskode („event handling code") (geschrieben von einem Entwickler, der die Komponente gebraucht) verwendet. Das Ausführungsbeispiel des Komponentenmodells wie unten beschrieben unterstützt sowohl single-cast als auch multi-cast Ereignisse.
  • Klassen und Schnittstellen
  • Im Folgenden wird dargelegt, wie Ereignisse gemäß dem vorliegenden Ausführungsbeispiel der Erfindung zur Verfügung gestellt und ausgenutzt werden können. Mehrere Klassen werden definiert und im Folgenden diskutiert:
    • 1) Die Klasse „Event". Des Ereignispackets interessierender Zustand in einem Ereignisobjekt. Alle solche Ereignisobjekte leiten sich von der Event-Klasse her. Die Event-Klasse wird also direkt für parameterlose Ereignisse verwendet.
    • 2) Der Delegat „EventHandler", der zusammen mit der Klasse „Event" verwendet wird.
    • 3) Die Klasse „CancelEvent", welche für stornierbare Handlungen verwendet wird. Bevor die Handlung vorgenommen wird, unterrichtet die Ereignisquelle interessierte Listener davon, dass die Handlung unmittelbar bevor steht. Jeder Listener hat die Möglichkeit, die Handlung zu „stornieren".
    • 4) Der Delegat „CancelEventHandler", die zusammen mit der Klasse „CancelEvent" verwendet wird.
  • Auslösen von Ereignissen
  • Um Ereignisse auszulösen macht die Ereignisquelle eines oder mehreres des Folgenden:
    • 1) Definieren einer Event-Klasse;
    • 2) Definieren eines „event handler" Delegaten;
    • 3) zur Verfügung stellen der Methoden „add" und „remove", um eine Ereignisquelle in die Lage zu versetzen, sich mit einem Ereignis zu verbinden und nachfolgend davon zu trennen; oder
    • 4) zur Verfügung stellen einer „Ereignis auslösen" („event raising") Methode, die ein Ereignis auslöst.
  • Definieren einer Eventklasse
  • Dies ist eine Klasse, die sich von der Klasse „Event" ableitet und potentiell Kontextinformationen hinzufügt. Es ist oftmals nicht notwendig eine neue Eventklasse zu definieren, da eine existierende Eventklasse verwendet werden kann.
  • Eventklassen werden nach Konvention verwendet. Es ist möglich Ereignisse zu definieren und zu verwenden, die Eventklassen überhaupt nicht benutzen. Das vorliegende Beispielkomponentenmodell empfiehlt das Verpacken von Ereignissen als Objekte um Ereignisverdrahtungsszenarios („event wiring scenarios") and Versionierung („versioning") zu ermöglichen. Diese Punkte werden im Folgenden diskutiert. Bei Mausereignissen, die durch eine „Window"-Klasse ausgelöst werden, möge die Eventklasse, wie in 9 gezeigt, definiert werden.
  • Definition eines „event handler" Delegaten
  • Jeweils ein Delegat wird für jede interessierende Menge von Ereignissen verwendet. Solch ein Delegat kann von mehreren Ereignissen verwendet werden. Nach Konvention werden „Event-Handler"-Delegate so definiert, dass sie der folgenden Struktur entsprechen:
    public multicast delegate void <Name>Handler (Object source, <EventType>e);
    Für das Mausereignis des Beispiels 44 von 9 impliziert dies:
    public multicast delegate void MouseEventHandler(Object source, MouseEvent e);
    Das Ausführungsbeispiel des hier beschriebenen Ereignishandhabungsmodells stellt „add" und „remove" Methoden zur Verfügung, die es einer Ereignisquelle ermöglichen, sich mit einem Ereignis zu verknüpfen und nachfolgend wieder davon zu lösen. Nach Konvention sind „Event-Handler"-Delegate so definiert, dass sie der folgenden Struktur entsprechen:
    public void
    addOn<EventName>Handler(<EventHandlerType> handler);
    public void
    removeOn<EventName>Handler(<EventHandlerType> handler);
    Für das Mausereignisbeispiel impliziert dies:
    public void addOnMouseMoveHandler(MouseEventHandler handler);
    public void removeOnMouseMoveHandler(MouseEventHandler handler);
    Bereitstellung einer "event raising" Methode, die ein Ereignis auslöst
  • Diese Methode ermöglicht abgeleiteten Klasse Ereignisse auszulösen, ein Ereignis zu löschen, welches in der Basisklasse ausgelöst wurde, und Pre- und Post-Bearbeitung zu ermöglichen, ohne Beeinträchtigung von Komponentenkonsumenten. Der Hauptteil der Methode löst das Ereignis aus, das „Delegate.invoke" auf das betreffende delegatenwertige Objekt aufzurufen, die Argumente zu übergeben und „this" als Wert des Quellenparameters für das Ereignis hinzuzufügen. Für „final"-Klassen gibt es keine Notwendigkeit solche Methode vorzusehen, da es abgeleiteten Klassen hier nicht möglich ist zu existieren. Nach Konvention sind „Event-Handler"-Delegate so definiert, dass sie der folgenden Struktur entsprechen:
    protected void on<EventName>(<EventType> e);
    Für das Mausereignisbeispiel ist die Methode 46, wie in 10 dargestellt, impliziert.
  • Handhabung von Ereignissen
  • Um Ereignisse abzuhören, tut ein Ereignis-Listener das Folgende:
    • 1) Lernen, welche Ereignisse einer Komponente zur Verfügung stehen, durch Benutzung der Klasse ComponentManager, welche in der JLS beschrieben ist.
    • 2) Erzeugen einer „Event-Handler"-Funktion mit der korrekten Signatur, wie sich durch den Delegaten definiert ist, der für die entsprechende Ereignissache verwendet wird, z.B. wie im Kode 48 der 11 gezeigt.
    • 3) Verbinden des „Event-Handling"-Kodes mit dem Ereignis durch Aufrufen der „add"-Methode der Ereignisquelle, z.B. wie gezeigt im Kode 50 der 12.
    • 4) Optional, Lösen des „Event-Handling"-Kodes vom Event durch Aufrufen der „remove" Methode, erzeugt durch die Quelle, wie beispielsweise gezeigt im Kode 52 der 13. In den meisten Fällen gibt es keinen Grund die Verbindung explizit zu lösen.
  • Erstes Beispiel des Ereignismodells im J++ Kode – Das „Box"-Beispiel
  • 14A-14B illustrieren den J++ Beispielkode 54, die Anwendung des oben beschriebenen Delegaten- und Ereignismodels zeigend. In den 14A-14B sind eine Mausereignisklasse und ein Mausereignishandhaber-Delegat deklariert. Eine „Box"-Klassendeklaration wird ausgeführt, sowie eine Darstellung eines Komponentenkonsumenten, welcher zwei „Box"-Instanzen verwendet.
  • Ein weiteres Beispiel eine Ereignismodells im J++ Kode – Das „Smiley"-Beispiel
  • Ein einfaches Ereignisbeispiel, wobei ein Ereignis ohne Parameter ausgelöst wird, ist in den 15A-15B dargestellt. Im J++ Programm 56 der 15A-15B, löst die „Smiley"-Aufsicht ein Ereignis aus, wenn sich ihre „happy" Eigenschaft ändert.
  • Single-Cast und Multi-Cast Ereignisse
  • Das oben beschriebene Ereignismodell arbeitet gleich gut für single-cast und multi-cast Szenarios. Nach bevorzugter Konvention dieses hier dargelegten Ausführungsbeispiels sind alle Ereignisse multi-cast. Die Definition eines single-cast Ereignisses ist einfach genug vorzunehmen, durch Auslassung des Multicast-Modifikators in der Delegatendeklaration. Ereignisse können sowohl in Klassen- als auch in Schnittstellendefinitionen auftreten. Es ist möglich eine Menge von Ereignissen in einer Schnittstelle zu definieren und mehrere Klassen die Schnittstelle zu unterstützen zu haben.
  • Der Hauptunterschied zwischen einem Multicast-Ereignis-Modell und einem Singlecast-Ereignis-Model liegt darin wie die Verbindung vorgenommen wird. Bei multi-cast ist es notwendig einen Multicast-Delegaten zu verwenden und die „addOn" und „removeOn"-Methoden zu benutzen. Für single-cast ist es möglich einen nicht-mulitcast Delegaten zu verwenden und Verbindung/Trennung mit einem Ereignis, vorgenommen durch Eigenschaften-„sets" and „gets", zu ermöglichen. Das heißt, eine Komponente weist eine delegatenwertige Eigenschaft für jedes der Ereignisse auf, die sie zur Verfügung stellt. Zum Beispiel beim MouseMove-Ereignis, würde eine Komponente ein „foo"-Ereignis zur Verfügung stellen, welches ein „OnFoo"-Eigenschaft zur Verfügung stellen würde, wie im Kode 58 in 16 dargestellt.
  • Die Klasse Event
  • Die Klasse Event dient mehreren Zwecken:
    • 1) Sie agiert als Basisklasse für alle Ereignisse. Nach Konvention verwenden Ereignisse von Komponenten einen einzigen Parameter, dessen Typ eine Klasse ist, die sich von der Klasse Event herleitet.
    • 2) Sie wird für Ereignisse verwendet, die keinen Zustand haben. Das statische Element EMPTY wird gewöhnlicherweise zu diesem Zwecke genutzt und erlaubt es, ein Ereignis effizient auszulösen, wie beispielhaft im Kode 60, dargestellt in 17, dargelegt.
  • Der Delegat „EventHandler"
  • Der Delegat „EventHandler" wird für Ereignisse verwendet, die einen einzigen Parameter des Typs Event akzeptieren, wie im Kode 62 der 18 gezeigt.
  • Die Klasse „CancelEvent"
  • Die „CancelEvent"-Klasse wird für Ereignisse verwendet, die sich auf eine Handlung beziehen, die storniert werden kann. Die „CancelEvent"-Klasse weist ein boolesches Feld mit dem Namen „cancel" auf, das aussagt, ob die in Frage kommende Handlung storniert werden muss. Ein „true"-Wert weist darauf hin, das die Handlung storniert wurde. Ein „false"-Wert weist darauf hin, dass die Handlung nicht storniert wurde. Ein anfänglicher Wert für „cancel" kann unter Verwendung des bereitgestellten Konstruktors erzeugt werden. Typischerweise wird „cancel" auf „false" gesetzt, so dass, wenn das Ereignis nicht behandelt wurde oder wenn der Event-Handler das „cancel"-Feld nicht verändert hat, die Ereignisquelle annimmt, dass die Erlaubnis zur Ausführung der Handlung gegeben wurde. Die „CancelEvent"-Klasse ist im Kode 64 der 19 gezeigt.
  • Der Delegat „CancelEventHandler"
  • Der Delegat „CancelEventHandler" wird für Ereignisse verwendet, die einen einzigen Parameter des Typs „CancelEvent" akzeptieren, wie im Kode 66 der 20 dargelegt.
  • Anderweitige Verwendung von Delegaten
  • Wie oben beschrieben sind Delegate im Allgemeinen nützlich, insbesondere für ereignisbezogene Szenarios. Jedoch sind sie auch nützlich für nicht-ereignisorientierte Szenarios, wie den Austausch des „Callback"-Mechanismus in „J/Direct" und „lazy invocation".
  • Anwendung der Erfindung auf andere Programmiersprachen und -systeme/Alternative Ausführungsbeispiele
  • Das hier beschriebene Ausführungsbeispiel der Delegaten- und Ereignismodelle der vorliegenden Erfindung sind als Erweiterung von Microsoft® Visual J++ ausgedrückt worden. Jedoch ist es verständlich, dass die hier beschriebene Erfindungen auch weitläufig auf andere objekt-orientierte Programmiersprachen, wie z. B. Microsoft® Visual Basic oder andere Versionen von J++ erhältlich von der Microsoft Corporation oder anderen Entwicklern, anwendbar sind.
  • Des Weiteren sind die hier dargelegten Erfindungen anwendbar auf und nehmen die Form an von Computerprogrammen, geschrieben im erfindungsgemäßen Kode der vorliegenden Erfindung, und Kompilierern wie auch Laufzeit-Virtuellen-Maschinen und anderen Programmiersystemen, welche Computerprogramme in auf einem Computer ausführbare Befehle übersetzen.
  • Die Erfindung ermöglicht ferner das Delegat- und Ereignismodelle in Gestalt von physikalischem Computerkode ausgebildet sein können, in oder auf einem Träger, wie z.B., aber nicht darauf beschränkt, Festplatten, flexible Disketten, Computerspeicher oder elektronischen Signalen, welche zum Transport eines solchen Kodes von einem Computer oder einem Speichermedium zu einem anderen verwendet werden könnten.
  • Ferner, obgleich die hier offenbarten Ausgestaltungen in Software implementiert sind, sind die hier ausgeführten Erfindungen in keinster Weise ausschließlich auf Implementierung in Software beschränkt, und daher werden ausdrücklich Implementierungen in Firmware und silikon-basierter oder anderer Formen von festverdrahteter Logik oder Kombinationen von festverdrahteter Logik, Firmware und Software oder jedem geeigneten Substitut davon genannt.

Claims (19)

  1. Ein objekt-basiertes Computerprogrammprodukt, bestehend aus einem Computerprogrammcode, enthalten in einer computerlesbaren Form auf einem physikalischen Träger (22; 24; 26; 28), wobei der Programmcode einen Computer (20) zur Ausführung der Schritte der Repräsentierung einer Instanz- und einer ersten Methode einer Klasse durch einen Delegiertenwert veranlasst, der Variablen zugewiesen und von einer Prozedur zur anderen gereicht werden kann; und des Aufrufens der ersten Methode durch Aufruf einer zweiten Methode einer Instanz einer Klasse unter Verwendung des Delegiertenwertes, wobei die Parameter, die der zweiten Methode übergeben werden, der ersten Methode übergeben werden, und die Parameterliste der zweiten Methode mit der Parameterliste der ersten Methode übereinstimmt und ferner wobei die erste Methode durch ihren Namen identifiziert und durch Übereinstimmung von Parameterliste und Ergebnis-Typ der ersten Methode mit der für die Klasse deklarierten Parameterliste und dem Ergebnis-Typ.
  2. Ein Computerprogrammprodukt gemäß Anspruch 1, ferner wobei die Instanz der Klasse durch einen Wert repräsentiert wird, der Variablen zugewiesen und von einer Prozedur zu einer anderen übergeben werden kann.
  3. Ein Computerprogrammprodukt gemäß Anspruch 2, ferner wobei der Programmcode den Computer (20) dazu veranlasst, die zweite Methode auf eine Variable hin aufzurufen, der ein Wert zugewiesen wurde, der eine Instanz einer Klasse repräsentiert.
  4. Ein Computerprogrammprodukt gemäß Anspruch 1, ferner wobei Ereignisse unter Verwendung der ersten Methode bearbeitet werden.
  5. Ein Computerprogrammprodukt gemäß Anspruch 1, ferner wobei der Computer (20) eine oder mehrere zusätzliche erste Methoden mit dem Aufruf der zweiten Methode aufruft, wobei eine oder mehrere entsprechende zusätzliche Sätze von Parametern der zweiten Methode zur Übergabe an die entsprechende eine oder mehrere zusätzliche erste Methode übergeben werden.
  6. Ein Computerprogrammprodukt gemäß Anspruch 5, ferner wobei eine mit der zweiten Methode assoziierte Aufrufliste kreiert wird, wobei die Aufrufliste die einzubindende erste Methode spezifiziert.
  7. Ein Computerprogrammprodukt gemäß Anspruch 6, ferner wobei erste Methoden der Aufrufliste hinzugefügt und entfernt werden.
  8. Ein objekt-basiertes Programmierungssystem, bestehend aus einem Computer (20) geeignet für die Repräsentierung einer Instanz und einer ersten Methode einer Klasse durch einen Delegiertenwert, der Variablen zugewiesen und von einer Prozedur zur anderen übergeben werden kann; und für den Aufruf einer ersten Methode durch einem Aufruf einer zweiten Methode einer Instanz einer Klasse unter Verwendung des Delegiertenwertes, wobei die der zweiten Methode übergebenen Parameter der ersten Methode übergeben werden und die Parameterliste der zweiten Methode mit der Parameterliste der ersten Methode übereinstimmt, und ferner wobei die erste Methode durch den Namen und durch Übereinstimmung von Parameterliste und Ergebnistyp der ersten Methode mit der für die Klasse deklarierten Parameterliste und dem Ergebnistyp identifiziert wird.
  9. Ein Programmierungssystem gemäß Anspruch 8, ferner wobei die Instanz der Klasse durch einen Wert repräsentiert wird, der Variablen zugewiesen und von einer Prozedur zur anderen übergeben werden kann.
  10. Ein Programmierungssystem gemäß Anspruch 9, ferner wobei der Programmcode den Computer (20) dazu veranlasst, die zweite Methode auf eine Variable hin aufzurufen, der ein Wert zugewiesen wurde, der eine Instanz einer Klasse repräsentiert.
  11. Ein Programmierungssystem gemäß Anspruch 8, ferner wobei Ereignisse unter Verwendung der ersten Methode bearbeitet werden.
  12. Ein Programmierungssystem gemäß Anspruch 8, ferner wobei der Computer eine oder mehrere zusätzliche erste Methoden mit einem Aufruf der zweiten Methode aufruft, wobei eine oder mehrere entsprechende zusätzliche Sätze von Parametern der zweiten Methode zur Übergabe an die entsprechende eine oder mehrere zusätzliche erste Methode übergeben werden.
  13. Ein Programmierungssystem gemäß Anspruch 12, ferner wobei eine mit der zweiten Methode assoziierte Aufrufliste kreiert wird, wobei die Aufrufliste die einzubindende erste Methode spezifiziert.
  14. Ein Programmierungssystem gemäß Anspruch 13, ferner wobei erste Methoden der Aufrufliste hinzugefügt und entfernt werden.
  15. Ein Programmierungssystem gemäß Anspruch 8, ferner wobei der Computer mit Software ausgestattet ist.
  16. Ein Programmierungssystem gemäß Anspruch 8, ferner wobei der Rechner mit Hardware und Software ausgestattet ist.
  17. Ein Programmierungssystem gemäß Anspruch 8, ferner wobei das Programmierungssystem einen Compiler (14) beinhaltet.
  18. Ein Programmierungssystem gemäß Anspruch 8, ferner wobei das Programmierungssystem einen Interpreter (16) umfasst.
  19. Ein Verfahren zur Programmierung eines Computers (20) im objekt-basierten Computercode, der die Verwendung eines Computers (20) zur Ausführung der folgenden Programmierschritte beinhaltet: a. definieren einer ersten Klasse, die eine erste Methode aufweist, die zur Referenz einer zweiten Methode einer zweiten Klasse verwendet wird; b. repräsentieren einer Instanz der ersten Klasse durch einem Delegiertenwert, wobei eine Instanz der zweiten Klasse und die zweite Methode als Parameter der Instanz der ersten Klasse identifiziert werden; und c. aufrufen einer zweiten Methode durch Aufrufen der ersten Methode auf die Instanz der ersten Klasse hin unter Verwendung des Wertes zur Referenz der Instanz.
DE69921474T 1998-06-03 1999-06-03 Methode-referenzierung in objektbasierter programmierung Expired - Lifetime DE69921474T2 (de)

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
US09/089,619 US6381734B1 (en) 1998-06-03 1998-06-03 Method, software and apparatus for referencing a method in object-based programming
US89619 1998-06-03
PCT/US1999/012299 WO1999063433A1 (en) 1998-06-03 1999-06-03 Referencing a method in object-based programming

Publications (2)

Publication Number Publication Date
DE69921474D1 DE69921474D1 (de) 2004-12-02
DE69921474T2 true DE69921474T2 (de) 2006-01-05

Family

ID=22218650

Family Applications (1)

Application Number Title Priority Date Filing Date
DE69921474T Expired - Lifetime DE69921474T2 (de) 1998-06-03 1999-06-03 Methode-referenzierung in objektbasierter programmierung

Country Status (7)

Country Link
US (1) US6381734B1 (de)
EP (1) EP1082654B1 (de)
JP (1) JP4220127B2 (de)
AT (1) ATE280973T1 (de)
DE (1) DE69921474T2 (de)
ES (1) ES2230900T3 (de)
WO (1) WO1999063433A1 (de)

Families Citing this family (33)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6918126B1 (en) * 2000-09-08 2005-07-12 International Business Machines Corporation Method and apparatus for creating and enforcing protected system level Java code
US7150001B1 (en) * 2001-03-19 2006-12-12 Microsoft Corporation System and method to facilitate design-time component discovery
US6934946B2 (en) * 2001-05-15 2005-08-23 Sun Microsystems, Inc. Lightweight native method invocation interface for java computing environments
US7152223B1 (en) * 2001-06-04 2006-12-19 Microsoft Corporation Methods and systems for compiling and interpreting one or more associations between declarations and implementations in a language neutral fashion
US7257603B2 (en) * 2003-05-08 2007-08-14 Microsoft Corporation Preview mode
US7634480B2 (en) 2003-05-08 2009-12-15 Microsoft Corporation Declarative rules for metadirectory
US7330853B2 (en) 2003-05-08 2008-02-12 Microsoft Corporation Attribute value selection for entity objects
US7636720B2 (en) * 2003-05-08 2009-12-22 Microsoft Corporation Associating and using information in a metadirectory
US20040225632A1 (en) * 2003-05-08 2004-11-11 Microsoft Corporation Automated information management and related methods
US7516157B2 (en) * 2003-05-08 2009-04-07 Microsoft Corporation Relational directory
US7620658B2 (en) * 2003-09-24 2009-11-17 Microsoft Corporation Configuration of a directory system
US7552450B1 (en) 2003-09-30 2009-06-23 Microsoft Corporation Systems and methods for enabling applications via an application programming interface (API) to interface with and configure digital media components
US8533597B2 (en) * 2003-09-30 2013-09-10 Microsoft Corporation Strategies for configuring media processing functionality using a hierarchical ordering of control parameters
US20070016292A1 (en) * 2003-11-14 2007-01-18 Edward Perez Epithelium treatment methods and devices for treating the epithelium
US20050246773A1 (en) * 2004-04-29 2005-11-03 Microsoft Corporation System and methods for processing partial trust applications
US7665062B1 (en) 2004-07-02 2010-02-16 Borland Software Corporation System and methodology for design-time dynamic class type construction
US7561673B2 (en) * 2004-09-30 2009-07-14 Microsoft Corporation Integration of speech services with telecommunications
US20070074185A1 (en) * 2005-08-30 2007-03-29 Microsoft Corporation Identifier expressions
US7694285B2 (en) * 2005-08-30 2010-04-06 Microsoft Corporation Relaxed and extended delegates
WO2007076629A1 (en) * 2005-12-30 2007-07-12 Intel Corporation Type checking for object-oriented programming languages
US7752596B2 (en) * 2006-03-17 2010-07-06 Microsoft Corporation Connecting alternative development environment to interpretive runtime engine
US7743087B1 (en) 2006-03-22 2010-06-22 The Math Works, Inc. Partitioning distributed arrays according to criterion and functions applied to the distributed arrays
WO2009104658A1 (ja) * 2008-02-19 2009-08-27 日本電気株式会社 情報表示装置、方法及びプログラム
US8234626B2 (en) 2008-06-04 2012-07-31 Dell Products L.P. Modular ASL component
US9569282B2 (en) * 2009-04-24 2017-02-14 Microsoft Technology Licensing, Llc Concurrent mutation of isolated object graphs
US20110055809A1 (en) * 2009-08-28 2011-03-03 International Business Machines Corporation Typed configuration management in programming languages
US20120159429A1 (en) * 2010-12-15 2012-06-21 Microsoft Corporation Metadata based eventing
US8793706B2 (en) 2010-12-16 2014-07-29 Microsoft Corporation Metadata-based eventing supporting operations on data
US20130212598A1 (en) * 2012-02-14 2013-08-15 Microsoft Corporation Dependency informer
US9626171B2 (en) 2015-07-24 2017-04-18 Oracle International Corporation Composing a module system and a non-module system
US10104090B2 (en) 2015-08-25 2018-10-16 Oracle International Corporation Restrictive access control for modular reflection
US10394528B2 (en) 2016-03-30 2019-08-27 Oracle International Corporation Returning a runtime type loaded from an archive in a module system
US10360008B2 (en) * 2016-09-16 2019-07-23 Oracle International Corporation Metadata application constraints within a module system based on modular encapsulation

Family Cites Families (26)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
AU639802B2 (en) * 1990-08-14 1993-08-05 Oracle International Corporation Methods and apparatus for providing dynamic invocation of applications in a distributed heterogeneous environment
AU628264B2 (en) * 1990-08-14 1992-09-10 Oracle International Corporation Methods and apparatus for providing a client interface to an object-oriented invocation of an application
US5265206A (en) * 1990-10-23 1993-11-23 International Business Machines Corporation System and method for implementing a messenger and object manager in an object oriented programming environment
US5421016A (en) * 1991-12-12 1995-05-30 International Business Machines Corporation System and method for dynamically invoking object methods from an application designed for static method invocation
US5515536A (en) * 1992-11-13 1996-05-07 Microsoft Corporation Method and system for invoking methods of an object through a dispatching interface
US5632034A (en) * 1993-06-01 1997-05-20 International Business Machines Corporation Controlling method invocation sequence through virtual functions in an object-oriented class library
DE69426143T2 (de) * 1993-09-10 2001-06-13 Sun Microsystems Inc Kundenseitiger Stubinterpretor
US5732271A (en) * 1995-01-23 1998-03-24 International Business Machines Corporation Data processing system and method for processing an object oriented development environment employing property inheritance using prototypical objects
US5680619A (en) * 1995-04-03 1997-10-21 Mfactory, Inc. Hierarchical encapsulation of instantiated objects in a multimedia authoring system
DE19535519C2 (de) * 1995-09-25 1999-03-04 Ibm Verfahren zur Reduzierung des Umfanges von Computerprogrammen
US5864862A (en) * 1996-09-30 1999-01-26 Telefonaktiebolaget Lm Ericsson (Publ) System and method for creating reusable components in an object-oriented programming environment
US6298476B1 (en) * 1995-12-04 2001-10-02 International Business Machines Corporation Object oriented software build framework mechanism
US5768505A (en) * 1995-12-19 1998-06-16 International Business Machines Corporation Object oriented mail server framework mechanism
US6104874A (en) * 1996-10-15 2000-08-15 International Business Machines Corporation Object oriented framework mechanism for order processing including pre-defined extensible classes for defining an order processing environment
US6002867A (en) * 1996-10-24 1999-12-14 Inprise Corporation Development system with methods providing visual form inheritance
US5937189A (en) * 1996-11-12 1999-08-10 International Business Machines Corporation Object oriented framework mechanism for determining configuration relations
US5991802A (en) * 1996-11-27 1999-11-23 Microsoft Corporation Method and system for invoking methods of objects over the internet
US5920720A (en) * 1997-02-25 1999-07-06 Microsoft Corporation Efficient computer based virtual machine object structure
US6182274B1 (en) * 1997-05-01 2001-01-30 International Business Machines Corporation Reusing code in object-oriented program development
US5941945A (en) * 1997-06-18 1999-08-24 International Business Machines Corporation Interest-based collaborative framework
US6014710A (en) * 1997-06-30 2000-01-11 Sun Microsystems, Inc. System and method for message transmission between network nodes using remote wires
US6078743A (en) * 1997-11-24 2000-06-20 International Business Machines Corporation Generic IDE interface support for scripting
US6199197B1 (en) * 1998-03-11 2001-03-06 International Business Machines Corporation Apparatus and method for providing common behavior across different processing levels in an object oriented framework
US6195791B1 (en) * 1998-03-11 2001-02-27 International Business Machines Corporation Object mechanism and method for coupling together processes to define a desired processing environment in an object oriented framework
US6275979B1 (en) * 1998-03-11 2001-08-14 International Business Machines Corporation Implementation for an object oriented run-time extensible item
US6083276A (en) * 1998-06-11 2000-07-04 Corel, Inc. Creating and configuring component-based applications using a text-based descriptive attribute grammar

Also Published As

Publication number Publication date
JP4220127B2 (ja) 2009-02-04
DE69921474D1 (de) 2004-12-02
ATE280973T1 (de) 2004-11-15
JP2002517815A (ja) 2002-06-18
US6381734B1 (en) 2002-04-30
EP1082654B1 (de) 2004-10-27
WO1999063433A1 (en) 1999-12-09
ES2230900T3 (es) 2005-05-01
EP1082654A1 (de) 2001-03-14

Similar Documents

Publication Publication Date Title
DE69921474T2 (de) Methode-referenzierung in objektbasierter programmierung
US6385769B1 (en) Text based object oriented program code with a visual program builder and parser support for predetermined and not predetermined formats
US5771384A (en) Method and system for replacement and extension of container interfaces
US6401101B1 (en) Method, server/computer and data structure for implementation of complex objects in an object-oriented database
DE69327448T2 (de) Verfahren und Vorrichtung für Teilaufgaben in verteiltem Verarbeitungssystem
DE69533530T2 (de) Verfahren und System zur dynamischen Aggregation von Objekten
Sakkinen Disciplined Inheritance.
US6633888B1 (en) Method and apparatus for visually creating and testing object oriented components
Clarke et al. Ownership types for flexible alias protection
DE69628965T2 (de) Verfahren und Gerät zum Verwalten von Beziehungen zwischen Objekten in einer verteilten Objektumgebung
US20040230559A1 (en) Information processing device and information processing method
DE69735343T2 (de) System, Verfahren und Vorrichtung zum direkten Ausführen eines architekturunabhängigen binären Programms
US6263498B1 (en) Method and apparatus for enabling server side distributed object modification
US7325226B2 (en) Modular object serialization architecture
EP1811447A1 (de) Deklarative Anpassung von in einem Objektspeicher bereitgestellten Softwareeinheiten
US20070074158A1 (en) Method and system for creating reusable software components through a uniform interface
DE60018505T2 (de) Vertraute Überprüfung von Rechnerprogrammodulen
DE60102694T2 (de) Modulares computersystem und -verfahren
EP1186996B1 (de) Programmierverfahren zum Ermöglichen von Polymorphismus
DE69636141T2 (de) Rechnerimplementiertes Verfahren zur Bestimmung eines Minimalcodesets für ein ausführbares Programm in einem Datenverarbeitungssystem
Ramos Logics and OO-Data Bases: a declarative approach
DE102012209674A1 (de) Verfahren zum Umwandeln von Ausgangsdaten in Zieldaten gemäß ASN.1
DE102004040010A1 (de) Ablaufumgebung für graphische Programmierung von wiederverwendbaren Trägerdiensten und Komponenten
Tanca et al. and o: m@ t! s, such that c= resolvedyn (o: m@ t; Mmeth).
Späth et al. Discovering Inheritance, Polymorphism, and Interfaces

Legal Events

Date Code Title Description
8364 No opposition during term of opposition