|
|
.JAVA GLOSSAR K-M
K
Diese Zusammenfassung von Methoden
und Variablen zu Klassen
bezeichnet man als Kapselung. Sie stellt die zweite wichtige
Eigenschaft objektorientierter Programmiersprachen dar. Kapselung
hilft vor allem, die Komplexität der Bedienung eines
Objekts zu reduzieren. Um eine Lampe anzuschalten, muss man
nicht viel über den inneren Aufbau des Lichtschalters
wissen. Sie vermindert aber auch die Komplexität der
Implementierung, denn undefinierte Interaktionen mit anderen
Bestandteilen des Programms werden verhindert oder reduziert. |
|
Unter Windows werden alle Tastatureingaben
an die fokussierte Komponente gesendet. Ein Empfänger
für Key-Events muss das Interface
Key Listener implementieren und
bekommt Events des Typs KeyEvent übergeben. KeyEvent
erweitert die Klasse InputEvent, die ihrerseits aus ComponentEvent
abgeleitet ist, und stellt neben getID und getSource eine
ganze Reihe von Methoden zur
Verfügung, mit denen die Erkennung und Bearbeitung der
Tastencodes vereinfacht wird. Die Registrierung von Key-Events
erfolgt mit der Methode addKey Listener,
die auf allen Objekten des Typs Component oder daraus abgeleiteten
Klassen zur Verfügung steht:
Um die Funktionsweise dieser Methoden
im Zusammenspiel mit den Methoden
der Klasse KeyEvent besser verstehen zu können, wollen
wir zwischen Zeichentasten und Funktionstasten unterscheiden.
Zeichentasten sind dabei solche Tasten, mit denen Buchstaben,
Ziffern oder sonstige gültige Unicode-Zeichen eingegeben
werden, wie z.B. [a], [A], [B], [1], [2], [%], [+], aber auch
[ESC], [LEER] oder [TAB]. Zu den Funktionstasten gehören
beispielsweise [F1], [F2], [POS1] oder [CURSORLINKS], aber
auch die Umschalttasten [STRG], [ALT] und [UMSCHALT].
|
|
Klassen sind das wichtigste Strukturierungsmittel
objektorientierter Sprachen. Eine Klasse enthält eine
Menge von Variablen, die den
Zustand von Objekten dieser Klasse beschreiben, und eine Menge
von Methoden, die das Verhalten
der Objekte festlegen.
Klassen sind insofern schachtelbar, als ihre
Instanzvariablen vom Typ einer
Klasse sein können. Dabei ist es insbesondere erlaubt,
dass die Membervariablen von
demselben Typ wie die zu definierende Klasse sind. Da in Java
alle Objekte als Referenzen abgelegt werden, können auf
diese Weise rekursive Datentypen erzeugt und zur Konstruktion
von dynamischen Datenstrukturen verwendet werden.
|
|
Neben Klassenvariablen
gibt es in Java auch Klassenmethoden, d.h. Methoden,
die unabhängig von einer bestimmten Instanz existieren.
Sie werden auch als statische Methoden
bezeichnet. Klassenmethoden werden ebenfalls mit Hilfe des
static-Attributs deklariert und
- analog zu Klassenvariablen
- durch Voranstellen des Klassennamens aufgerufen.
Da Klassenmethoden unabhängig von konkreten
Instanzen ihrer Klasse existieren, ist ein Zugriff auf Instanzvariablen
nicht möglich. Diese Trennung äußert sich
darin, dass Klassenmethoden keinen this-Zeiger
besitzen. Der Zugriff auf Instanzvariablen
und der Aufruf von Instanzmethoden wird daher schon zur Compile-Zeit
als Fehler erkannt.
Klassenmethoden werden häufig da eingesetzt,
wo Funktionalitäten zur Verfügung gestellt werden,
die nicht datenzentriert arbeiten oder auf primitiven Datentypen
operieren. Beispiele für beide Arten sind in der Klassenbibliothek
zu finden. Zur ersten Gruppe gehören beispielsweise die
Methoden der Klasse System. Die
Klasse System ist eine Art Toolbox, die Funktionen wie Aufruf
des Garbage Collectors oder Beenden des Programms zur Verfügung
stellt. Zur zweiten Gruppe gehören beispielsweise die
Methoden der Klasse Math, die
eine große Anzahl an Funktionen zur Fließkomma-Arithmetik
zur Verfügung stellen. Da die Fließkommatypen primitiv
sind, hätte ein instanzbasiertes Methodendesign an dieser
Stelle wenig Sinn.
Eine weitere Anwendung für Klassenmethoden
liegt in der Instanzierung von Objekten der eigenen Klasse.
Beispiele dafür finden sich in den Design-Patterns Singleton
und Factory-Methode.
|
|
Mit der Methode getClass der Klasse
Object besitzt ein beliebiges
Objekt die Fähigkeit, ein passendes Klassenobjekt zu
liefern. Zu jeder Klasse, die das Laufzeitsystem verwendet,
wird während des Ladevorgangs ein Klassenobjekt vom Typ
Class erzeugt. Die Klasse Class
stellt Methoden zur Abfrage von
Eigenschaften der Klasse zur
Verfügung und erlaubt es, Klassen
dynamisch zu laden und Instanzen dynamisch zu erzeugen. Darüber
hinaus ist sie der Schlüssel zur Funktionalität
des Reflection-APIs. |
|
Java ist eine konsequent objektorientierte
Sprache, in der es weder globale
Funktionen noch globale Variablen gibt. Da es aber mitunter
sinnvoll ist, Eigenschaften zu verwenden, die nicht an Instanzen
einer Klasse gebunden sind, haben die Sprachdesigner das Attribut
static für Methoden
und Variablen eingeführt.
Eine Variable, die innerhalb einer Klasse
mit dem Attribut static versehen
wurde, nennt man Klassenvariable (oder auch Statische
Variable). Im Gegensatz zu Instanzvariablen,
die immer an ein konkretes Objekt gebunden sind, existieren
Klassenvariablen unabhängig von einem Objekt.
Jede Klassenvariable wird nur einmal angelegt
und kann von allen Methoden der
Klasse aufgerufen werden. Da
sich alle Methoden die Variable
»teilen«, sind Veränderungen, die eine Instanz
vornimmt, auch in allen anderen Instanzen sichtbar. Klassenvariablen
sind daher vergleichbar mit globalen Variablen, denn ihre
Lebensdauer erstreckt sich auf das gesamte Programm. Namenskollisionen
können allerdings nicht auftreten, denn der Zugriff von
außen erfolgt durch Qualifizierung mit dem Klassennamen
in der Form Klassenname.Variablenname.
|
|
In jeder objektorientierten Programmiersprache
lassen sich spezielle Methoden
definieren, die bei der Initialisierung
eines Objekts aufgerufen werden: die Konstruktoren. In Java
werden Konstruktoren als Methoden
ohne Rückgabewert definiert, die den Namen der Klasse
erhalten, zu der sie gehören. Konstruktoren dürfen
eine beliebige Anzahl an Parametern haben und können
überladen werden. |
|
L
Interessant wird Polymorphismus,
wenn die Programmiersprache zusätzlich das Konzept des
Late Binding implementiert. Im Unterschied zum "Early
Binding" wird dabei nicht bereits zur Compilezeit entschieden,
welche Ausprägung einer bestimmten Methode aufgerufen
werden soll, sondern erst zur Laufzeit. Wenn beispielsweise
auf einem Objekt der Klasse X eine Methode mit dem Namen f
aufgerufen werden soll, ist zwar prinzipiell bereits zur Compilezeit
klar, wie der Name lautet. Objektorientierte Programmiersprachen
erlauben aber das Überlagern
von Methoden in abgeleiteten
Klassen, und da - wie zuvor erwähnt
- eine Objektvariable des Typs
X auch Objekte aus allen von X abgeleiteten Klassen
aufnehmen kann, könnte f in einer dieser nachgelagerten
Klassen überlagert worden
sein. Welche konkrete Methode also aufgerufen werden muss,
kann damit erst zur Laufzeit entschieden werden. |
|
Leere Anweisung
|
Die leere Anweisung |
Die einfachste Anweisung in Java ist
die leere Anweisung. Sie besteht nur aus dem Semikolon und
hat keinerlei Effekt auf das laufende Programm. Eine leere
Anweisung kann da verwendet werden, wo syntaktisch eine Anweisung
erforderlich ist, aber von der Programmlogik her nichts zu
tun ist. |
|
Listener
|
Das Observer-Pattern |
Das Observer-Pattern ist in Java sehr
verbreitet, denn die Kommunikation zwischen graphischen Dialogelementen
und ihrer Anwendung basiert vollständig auf dieser Idee.
Allerdings wurde es etwas erweitert, die Beobachter werden
als Listener bezeichnet, und es gibt von ihnen eine Vielzahl
unterschiedlicher Typen mit unterschiedlichen Aufgaben. Da
es zudem üblich ist, dass ein Listener sich bei mehr
als einem Subjekt registriert, wird ein Aufruf von update
statt des einfachen Arguments jeweils ein Listener-spezifisches
Ereignisobjekt übergeben. Darin werden neben dem Subjekt
weitere spezifische Informationen untergebracht. Zudem haben
die Methoden gegenüber der
ursprünglichen Definition eine andere Namensstruktur,
und es kann sein, dass ein Listener nicht nur eine, sonderen
mehrere unterschiedliche Update-Methoden zur Verfügung
stellen muss, um auf unterschiedliche Ereignistypen zu reagieren.
Das Listener-Konzept von Java wird auch als Delegation Based
Event Handling bezeichnet. |
|
Ein Buchstabe im Sinne des Unicode-Zeichensatzes
muss nicht zwangsläufig aus dem lateinischen Alphabet
stammen. Es ist auch zulässig, Buchstaben aus anderen
Landessprachen zu verwenden. Java-Programme können daher
ohne weiteres Bezeichner enthalten,
die nationalen Konventionen folgen. Java-Bezeichner
dürfen jedoch nicht mit Schlüsselwörtern, den
booleschen Literalen true und
false oder dem Literal null kollidieren.
Logische Typen: Der Datentyp boolean
kennt zwei verschiedene Werte, nämlich true
und false. Neben den vordefinierten Konstanten gibt es keine
weiteren Literale für logische Datentypen.
Zeichentypen: char-Literale werden grundsätzlich in einfache
Hochkommata gesetzt. Daneben gibt es String-Literale,
die in doppelten Hochkommata stehen. Ähnlich wie C stellt
Java eine ganze Reihe von Standard-Escape-Sequenzen zur Verfügung,
die zur Darstellung von Sonderzeichen verwendet werden können.
Integrale Typen: Ganzzahlige Literale können in Dezimal-,
Oktal- oder Hexadezimalform geschrieben werden. Ein oktaler
Wert beginnt mit dem Präfix 0, ein hexadezimaler Wert
mit 0x. Dezimale Literale dürfen nur aus den Ziffern
0 bis 9, oktale aus den Ziffern 0 bis 7 und hexadezimale aus
den Ziffern 0 bis 9 und den Buchstaben a bis f und A bis F
bestehen. Durch Voranstellen eines - können negative
Zahlen dargestellt werden, positive können wahlweise
durch ein + eingeleitet werden. Ganzzahlige Literale sind
grundsätzlich vom Typ int, wenn nicht der Suffix L oder
l hinten angehängt wird. In diesem Fall sind sie vom
Typ long.
Fließkommazahlen: Fließkommaliterale werden immer
in Dezimalnotation aufgeschrieben. Sie bestehen aus einem
Vorkommateil, einem Dezimalpunkt, einem Nachkommateil, einem
Exponenten und einem Suffix. Um ein Fließkommaliteral
von einem integralen Literal unterscheiden zu können,
muss mindestens der Dezimalpunkt, der Exponent oder der Suffix
vorhanden sein. Entweder der Vorkomma- oder der Nachkommateil
darf ausgelassen werden, aber nicht beide. Vorkommateil und
Exponent können wahlweise durch das Vorzeichen + oder
- eingeleitet werden. Weiterhin ist der Exponent, der durch
ein e oder E eingeleitet wird, optional. Auch der Suffix kann
weggelassen werden, wenn durch die anderen Merkmale klar ist,
dass es sich um eine Fließkommazahl handelt. Der Suffix
kann entweder f oder F sein, um anzuzeigen, dass es sich um
ein float handelt, oder d oder D, um ein double anzuzeigen.
Fehlt er, so ist das Literal (unabhängig von seiner Größe)
vom Typ double.
|
|
Logische Operatoren
dienen dazu, boolesche Werte miteinander zu verknüpfen.
Im Gegensatz zu den relationalen Operatoren, die durch Vergleiche
erst Wahrheitswerte produzieren, werden logische Operatoren
zur Weiterverarbeitung von Wahrheitswerten verwendet. Java
stellt die Grundoperationen UND, ODER und NICHT zur Verfügung
und bietet darüber hinaus die Möglichkeit, das Auswertungsverhalten
der Operanden zu beeinflussen. Anders als die meisten anderen
Programmiersprachen, stellt Java die UND- und ODER-Verknüpfungen
in zwei verschiedenen Varianten zur Verfügung, nämlich
mit Short-Circuit-Evaluation oder ohne.
Bei der Short-Circuit-Evaluation eines logischen
Ausdrucks wird ein weiter rechts stehender Teilausdruck nur
dann ausgewertet, wenn er für das Ergebnis des Gesamtausdrucks
noch von Bedeutung ist. Falls in dem Ausdruck A &&
B also bereits A falsch ist, wird zwangsläufig immer
auch A && B falsch sein, unabhängig von dem Resultat
von B. Bei der Short-Circuit-Evaluation wird in diesem Fall
B gar nicht mehr ausgewertet. Analoges gilt bei der Anwendung
des ODER-Operators.
|
|
Die Definition einer
nicht-statischen lokalen Klasse entspricht genau dem zuvor
beschriebenen Grundprinzip: innerhalb des Definitionsteils
einer beliebigen Klasse wird eine neue Klasse definiert. Ihre
Instanzierung muß innerhalb der äußeren Klasse
erfolgen, also in einer der Methoden
der äußeren Klasse oder während ihrer Initialisierung.
Die innere Klasse kann auf die
Membervariablen der äußeren
Klasse zugreifen und umgekehrt.
Die Implementierung von lokalen Klassen konnte
im JDK 1.1 ohne größere Änderungen der virtuellen
Maschine vorgenommen werden. Lokale Klassen sind zwar zum
Compilezeitpunkt bekannt, werden aber zur Laufzeit behandelt
wie normale Klassen. Insbesondere wird vom Compiler zu jeder
lokalen Klasse eine eigene .class-Datei
erzeugt. Um Überschneidungen zu vermeiden, besteht ihr
Name aus dem Namen der äußeren Klasse, gefolgt
von einem Dollarzeichen und dem Namen der inneren Klasse.
Bei den später behandelten anonymen
Klassen wird statt des Namens der inneren Klasse eine
vom Compiler vergebene fortlaufende Nummer verwendet.
Klassen in Methoden
Innere Klassen können nicht
nur auf der äußersten Ebene einer anderen Klasse
definiert werden, sondern auch innerhalb ihrer Methoden und
sogar innerhalb eines beliebigen Blocks. In diesem Fall können
sie auch auf die lokalen Variablen
der umgebenden Methode oder des umgebenden Blocks zugreifen.
Bedingung ist allerdings, daß diese mit Hilfe des Schlüsselworts
final als konstant deklariert
wurden.
|
|
Lokale Variablen,
die innerhalb einer Methode oder eines Blocks definiert werden
und nur dort existieren.
Lokale Variablen dürfen sich nicht gegenseitig
verdecken. Es ist also nicht erlaubt, eine bereits deklarierte
Variable x in einem tiefer geschachtelten Block erneut zu
deklarieren. Das Verdecken von Klassen- oder Instanzvariablen
dagegen ist zulässig und wird besonders häufig in
Konstruktoren bei der Initialisierung
von Instanzvariablen verwendet.
|
|
M
Ein schon bekanntes
Beispiel für eine Klassenmethode ist die Methode
main, die als Startpunkt in Applikationen
verwendet wird. Im Gegensatz zu Applets,
bei denen vom Laufzeitsystem eine Instanz der Appletklasse
erzeugt und dann durch Aufruf von Callback-Methoden bedient
wird, erfolgt der Start einer Applikation
ohne die Instanzierung einer Klasse.
Der Java-Interpreter lädt lediglich das beim Starten
angegebene Klassenobjekt und
sucht nach einer statischen Methode mit der Signatur:
public static
void main(String[]
args)
Wird diese gefunden, stellt es ein Array mit den Kommandozeilenparametern
zusammen und übergibt es als Argument an main. Wird keine
Methode mit dieser Signatur gefunden,
gibt es einen Laufzeitfehler.
Technisch betrachtet ist eine Applikation
nicht mehr als eine einzelne Klasse, in der eine Methode vom
Typ public static
void main definiert wurde. Jede
Klasse, die eine solche Methode enthält, kann als Applikation
verwendet werden. Durch einfaches Hinzufügen einer Methode
public static
void main kann also jede beliebige
Klasse sehr leicht in eine Applikation
verwandelt und vom Java-Interpreter aufgerufen werden. Dies
kann beispielsweise nützlich sein, um in Low-Level-Klassen,
die eigentlich nur als Dienstleister auftreten, eigenständig
ausführbaren Testcode unterzubringen, oder um eine solche
Klasse mit Benutzungshinweisen auszustatten, die der Entwickler
durch einfaches Starten der Klasse
als Applikation abrufen kann.
Eine Applikation
wird gestartet, indem vom Java-Interpreter die Klassenmethode
main aufgerufen wird. Das Starten eines Applets
wird dadurch erreicht, daß der Web-Browser die Applet-Klasse
instanziert und die Methoden
init und start aufruft.
|
|
meta-inf
|
Die Manifest-Datei |
Um eine jar-Datei
selbst »ausführbar« zu machen, müssen
wir eine Manifest-Datei erstellen, in der der Name der Klasse
angegeben wird, die die main-Methode
enthält. Anschließend lässt sich die jar-Datei
mir der Option -jar des Interpreters ohne explizite Angabe
der Hauptklasse starten.
Die Manifest-Datei ist eine Hilfsdatei mit Informationen über
den Inhalt der jar-Datei. Sie
hat den Namen manifest.mf und liegt im Unterverzeichnis meta-inf
des jar-Archivs. Die Manifest-Datei kann mit einem normalen
Texteditor erstellt und mit Hilfe der Option "m"
in das jar-Archiv eingebunden
werden. In unserem Fall muß sie lediglich einen Eintrag
Main-Class enthalten.
Um bei GUI-Designern mit einer großen Anzahl unterschiedlicher
Beans ein schwer zu durchschauendes Sammelsurium kleiner Klassendateien
zu vermeiden, werden Beans in jar-Archive
verpackt und so an den GUI-Designer übergeben. Eine jar-Datei
darf beliebig viele Beans enthalten. Um dem GUI-Designer die
Möglichkeit zu geben, Klassen
für Beans von solchen mit reinen Hilfsfunktionen zu unterscheiden,
wird dem jar-Archiv eine Manifest-Datei
hinzugefügt, die ihren Inhalt beschreibt. Es handelt
sich um eine normale Textdatei, die für jede enthaltene
Bean einen Eintrag der folgenden Form enthält:
Name: BeanClassFile.class
Java-Bean: True
Der erste Eintrag gibt den Klassennamen an. Der zweite besagt,
dass es sich um eine Bean handelt (Manifest-Dateien können
auch noch andere Informationen über die im Archiv gespeicherten
Dateien enthalten). Die Informationen werden zweckmäßigerweise
in eine Textdatei manifest.txt geschrieben und beim Erzeugen
der jar-Datei mit der Option
"m" eingebunden. |
|
In manchen objektorientierten Programmiersprachen
kann eine abgeleitete Klasse mehr als eine Basisklasse besitzen
(z.B. in C++ oder Eiffel). In diesem Fall spricht man von
Mehrfach vererbung. Die Vererbungshierarchie
ist dann nicht mehr zwangsläufig ein Baum, sondern muss
zu einem gerichteten Graph verallgemeinert werden. In Java
gibt es allerdings keine Mehrfach vererbung,
und wir wollen daher nicht weiter auf die Besonderheiten dieser
Technik eingehen.
Man unterscheidet dabei zwischen einfacher
Vererbung, bei der eine Klasse
von maximal einer anderen Klasse abgeleitet werden kann, und
Mehrfachvererbung, bei der eine Klasse von mehr als einer
anderen Klasse abgeleitet werden kann. In Java gibt es lediglich
Einfachvererbung, um den Problemen
aus dem Weg zu gehen, die durch Mehrfachvererbung entstehen
können. Um die Einschränkungen in den Designmöglichkeiten,
die bei Einfachvererbung entstehen, zu vermeiden, wurde mit
Hilfe der Interfaces eine neue,
restriktive Art der Mehrfachvererbung eingeführt.
Es wurde bereits erwähnt, dass es in Java keine Mehrfachvererbung
von Klassen gibt. Die möglichen Schwierigkeiten beim
Umgang mit mehrfacher Vererbung
und die Einsicht, dass das Erben nichttrivialer Methoden
aus mehr als einer Klasse in der Praxis selten zu realisieren
ist, haben die Designer dazu veranlasst, dieses Feature nicht
zu implementieren.
|
|
Mehrdimensionale
Arrays werden erzeugt, indem zwei oder mehr Paare eckiger
Klammern bei der Deklaration angegeben werden. Mehrdimensionale
Arrays werden als Arrays von Arrays angelegt. Die Initialisierung
erfolgt analog zu eindimensionalen Arrays durch Angabe der
Anzahl der Elemente je Dimension.
Der Zugriff auf mehrdimensionale Arrays geschieht
durch Angabe aller erforderlichen Indizes, jeweils in eigenen
eckigen Klammern. Auch bei mehrdimensionalen Arrays kann eine
literale Initialisierung
durch Schachtelung der Initialisierungssequenzen erreicht
werden.
|
|
In objektorientierten Programmiersprachen
wird eine Klasse durch die Zusammenfassung einer Menge von
Daten und darauf operierender Funktionen (die nun Methoden
genannt werden) definiert. Die Daten werden durch einen Satz
Variablen repräsentiert,
der für jedes instanziierte Objekt neu angelegt wird
(diese werden als Attribute, Membervariablen, Instanzvariablen
oder Instanzmerkmalebezeichnet). Die Methoden
sind im ausführbaren Programmcode nur einmal vorhanden,
operieren aber bei jedem Aufruf auf den Daten eines ganz bestimmten
Objekts (das Laufzeitsystem übergibt bei jedem Aufruf
einer Methode einen Verweis auf
den Satz Instanzvariablen, mit
dem die Methode gerade arbeiten
soll).
Die innerhalb einer Klasse definierten Variablen
werden (analog zu C++) meist als Membervariablen bezeichnen.
Die erwähnten Begriffe Instanzvariablen oder Instanzmerkmal
sind aber ebenso gültig.
|
|
Methoden definieren das Verhalten von
Objekten. Sie werden innerhalb einer Klassendefinition angelegt
und haben Zugriff auf alle Variablen
des Objekts. Methoden sind das Pendant zu den Funktionen anderer
Programmiersprachen, arbeiten aber immer mit den Variablen
des aktuellen Objekts. Globale Funktionen,
die vollkommen unabhängig von einem Objekt oder einer
Klasse existieren, gibt es in
Java ebensowenig wie globale Variablen. Wir werden später
allerdings Klassenvariablen und
-methoden kennenlernen, die nicht an eine konkrete Instanz
gebunden sind. Die Syntax der Methodendefinition in Java ähnelt
der von C/C++. [ Membervariablen]
Methoden sind
wie Blöcke Kollektionen, die Deklarationen und Anweisungen
enthalten können. Genaugenommen enthalten sie neben dem
Funktionskopf genau einen Block, der alle anderen Elemente
enthält. Sie unterscheiden sich von Blöcken folgendermaßen:
· Sie haben einen Namen und können
von verschiedenen Stellen des Programms aus aufgerufen werden
· Sie sind parametrisierbar, und ihr
Verhalten ist so zur Laufzeit strukturiert veränderbar
· Sie können einen Rückgabewert
haben, mit dem ein Wert an den Aufrufer zurückgegeben
werden kann
In Java gibt es keine Funktionen, sondern
nur Methoden. Der Unterschied zwischen beiden besteht darin,
dass Methoden immer an eine Klasse
oder die Instanz einer Klasse gebunden sind und nur in diesem
Kontext aufgerufen werden können. Klassenlose Funktionen,
wie sie beispielsweise in C++ zur Verfügung stehen, gibt
es in Java nicht. In diesem Sinne ist Java eine wirklich objektorientierte
Programmiersprache, denn die Methoden operieren immer auf
den Daten eines bestimmten Objekts, zu dem sie aufgerufen
werden. Die Syntax des Methodenaufrufs gleicht der anderer
Programmiersprachen und erfolgt in der (etwas vereinfachten)
Form f() bzw. f(parameterliste). Der Typ des Ausdrucks entspricht
dem vereinbarten Rückgabetyp der Methode. Der Wert des
Ausdrucks ist der von der Methode mit Hilfe der return-Anweisung
zurückgegebene Wert.
Allerdings gibt es noch die Klassenmethoden.
Sie werden zwar auch innerhalb einer Klasse definiert, benötigen
aber später kein Objekt zur Ausführung. Statt dessen
entsprechen Klassenmethoden eher
den globalen Funktionen anderer
Programmiersprachen und haben somit keinen Zugriff auf die
Membervariablen eines Objekts.
Im Unterschied zu gewöhnlichen Funktionen werden Klassenmethoden
aber innerhalb einer Klasse definiert und besitzen damit einen
eigenen Namensraum, der sich über die Methoden
der aktuellen Klasse erstreckt.
Der Zugriff auf eine Klassenmethode erfordert immer die Verwendung
eines qualifizierten Namens, der sich aus dem Klassennamen,
einem Punkt und dem eigentlichen Methodennamen zusammensetzt.
|
|
MVC
|
Das Model-View-Controller-Prinzip
/ Model-Delegate-Prinzip |
Neben den äußerlichen
Qualitäten wurde auch die Architektur des Gesamtsystems
verbessert. Wichtigste "Errungenschaft" ist dabei
das Model-View-Controller-Prinzip (kurz MVC genannt), dessen
Struktur sich wie ein roter Faden durch den Aufbau der Dialogelemente
zieht. Anstatt den gesamten Code in eine einzelne Klasse zu
packen, werden beim MVC-Konzept drei unterschiedliche Bestandteile
eines grafischen Elements sorgsam unterschieden:
· Das Modell enthält die Daten
des Dialogelements und speichert seinen Zustand.
· Der View ist für die grafische
Darstellung der Komponente verantwortlich.
· Der Controller wirkt als Verbindungsglied
zwischen beiden. Er empfängt Tastatur- und Mausereignisse
und stößt die erforderlichen Maßnahmen zur
Änderung von Model und View an.
Das Modell enthält praktisch die gesamte
Verarbeitungslogik der Komponente. Ein wichtiger Aspekt ist
dabei, dass ein Model mehrere Views gleichzeitig haben kann.
Damit Veränderungen des Modells in allen Views sichtbar
werden, wird ein Benachrichtigungsmechanismus implementiert,
mit dem das Modell die zugeordneten Views über Änderungen
informiert. Diese Vorgehensweise entspricht dem Observer-Pattern.
Bei den Swing-Dialogelementen
wird eine vereinfachte Variante von MVC verwendet, die auch
als Model-Delegate-Prinzip bezeichnet wird. Hierbei wird die
Funktionalität von View und Controller in einem UI Delegate
zusammengefaßt. Dadurch wird einerseits die Komplexität
reduziert (oft ist der Controller so einfach strukturiert,
dass es sich nicht lohnt, ihn separat zu betrachten) und andererseits
die in der Praxis mitunter unhandliche Trennung zwischen View
und Controller aufgehoben. Es kann allerdings sein, dass ein
Dialogelement mehr als ein Model besitzt. So haben beispielsweise
Listen und Tabellen neben ihrem eigentlichen Datenmodell ein
weiteres, das nur für die Selektion von Datenelementen
zuständig ist.
|
|
Quelle: Java - Glossary zusammengestellt aus „Go To Java 2“,
Zweite Auflage, Addison Wesley, Version 2.0 © 2000 Guido Krüger
|
|