Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Mathematisches
6 Eigene Klassen schreiben
7 Angewandte Objektorientierung
8 Exceptions
9 Die Funktionsbibliothek
10 Threads und nebenläufige Programmierung
11 Raum und Zeit
12 Datenstrukturen und Algorithmen
13 Dateien und Datenströme
14 Die eXtensible Markup Language (XML)
15 Grafische Oberflächen mit Swing
16 Grafikprogrammierung
17 Netzwerkprogrammierung
18 Verteilte Programmierung mit RMI und Web-Services
19 JavaServer Pages und Servlets
20 Applets
21 Midlets und die Java ME
22 Datenbankmanagement mit JDBC
23 Reflection und Annotationen
24 Logging und Monitoring
25 Sicherheitskonzepte
26 Java Native Interface (JNI)
27 Dienstprogramme für die Java-Umgebung
A Die Begleit-DVD
Stichwort

Download:
- ZIP, ca. 12,5 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel

Java ist auch eine Insel
7., aktualisierte Auflage
geb., mit DVD (November 2007)
1.492 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1146-8
Pfeil 6 Eigene Klassen schreiben
Pfeil 6.1 Eigene Klassen mit Eigenschaften deklarieren
Pfeil 6.1.1 Attribute deklarieren
Pfeil 6.1.2 Methoden deklarieren
Pfeil 6.1.3 Die this-Referenz
Pfeil 6.2 Privatsphäre und Sichtbarkeit
Pfeil 6.2.1 Für die Öffentlichkeit: public
Pfeil 6.2.2 Paketsichtbar
Pfeil 6.2.3 Kein Public Viewing – Passwörter sind privat
Pfeil 6.2.4 Wieso nicht freie Methoden und Variablen für alle?
Pfeil 6.2.5 Privat ist nicht ganz privat: Es kommt darauf an, wer’s sieht
Pfeil 6.2.6 Zugriffsmethoden für Attribute deklarieren
Pfeil 6.2.7 Setter und Getter nach der JavaBeans-Spezifikation
Pfeil 6.3 Statische Methoden und statische Attribute
Pfeil 6.3.1 Warum statische Eigenschaften sinnvoll sind
Pfeil 6.3.2 Statische Eigenschaften mit static
Pfeil 6.3.3 Statische Eigenschaften über Referenzen nutzen?
Pfeil 6.3.4 Warum die Groß- und Kleinschreibung wichtig ist
Pfeil 6.3.5 Statische Eigenschaften und Objekteigenschaften
Pfeil 6.3.6 Statische Variablen zum Datenaustausch
Pfeil 6.3.7 Statische Blöcke als Klasseninitialisierer
Pfeil 6.4 Konstanten und Aufzählungen
Pfeil 6.4.1 Konstanten über öffentliche statische finale Variablen
Pfeil 6.4.2 Eincompilierte Belegungen der Klassenvariablen
Pfeil 6.4.3 Typ(un)sicherere Aufzählungen
Pfeil 6.4.4 Aufzählungen mit enum
Pfeil 6.5 Objekte anlegen und zerstören
Pfeil 6.5.1 Konstruktoren schreiben
Pfeil 6.5.2 Der Standard-Konstruktor
Pfeil 6.5.3 Parametrisierte und überladene Konstruktoren
Pfeil 6.5.4 Konstruktor nimmt ein Objekt vom eigenen Typ an (Copy-Konstruktor)
Pfeil 6.5.5 Einen anderen Konstruktor der gleichen Klasse aufrufen
Pfeil 6.5.6 Initialisierung der Objekt- und Klassenvariablen
Pfeil 6.5.7 Finale Werte im Konstruktor und in statischen Blöcken setzen
Pfeil 6.5.8 Exemplarinitialisierer (Instanzinitialisierer)
Pfeil 6.5.9 Ihr fehlt uns nicht – der Garbage-Collector
Pfeil 6.5.10 Implizit erzeugte String-Objekte
Pfeil 6.5.11 Private Konstruktoren, Utility-Klassen, Singleton, Fabriken
Pfeil 6.6 Assoziationen zwischen Objekten
Pfeil 6.6.1 Unidirektionale 1:1-Beziehung
Pfeil 6.6.2 Bidirektionale 1:1-Beziehungen
Pfeil 6.6.3 Unidirektionale 1:n-Beziehung
Pfeil 6.7 Vererbung
Pfeil 6.7.1 Vererbung in Java
Pfeil 6.7.2 Spielobjekte modelliert
Pfeil 6.7.3 Einfach- und Mehrfachvererbung
Pfeil 6.7.4 Sichtbarkeit protected
Pfeil 6.7.5 Konstruktoren in der Vererbung und super
Pfeil 6.7.6 Automatische und explizite Typanpassung
Pfeil 6.7.7 Das Substitutionsprinzip
Pfeil 6.7.8 Typen mit dem binären Operator instanceof testen
Pfeil 6.7.9 Methoden überschreiben
Pfeil 6.7.10 Mit super an die Eltern
Pfeil 6.7.11 Kovariante Rückgabetypen
Pfeil 6.7.12 Array-Typen und Kovarianz
Pfeil 6.7.13 Zusammenfassung zur Sichtbarkeit
Pfeil 6.8 Dynamisches Binden
Pfeil 6.8.1 Unpolymorph bei privaten, statischen und finalen Methoden
Pfeil 6.8.2 Polymorphie bei Konstruktoraufrufen
Pfeil 6.8.3 Finale Klassen
Pfeil 6.8.4 Nicht überschreibbare (finale) Methoden
Pfeil 6.9 Abstrakte Klassen und abstrakte Methoden
Pfeil 6.9.1 Abstrakte Klassen
Pfeil 6.9.2 Abstrakte Methoden
Pfeil 6.10 Schnittstellen
Pfeil 6.10.1 Deklarieren von Schnittstellen
Pfeil 6.10.2 Implementieren von Schnittstellen
Pfeil 6.10.3 Markierungsschnittstellen
Pfeil 6.10.4 Ein Polymorphie-Beispiel mit Schnittstellen
Pfeil 6.10.5 Die Mehrfachvererbung bei Schnittstellen
Pfeil 6.10.6 Keine Kollisionsgefahr bei Mehrfachvererbung
Pfeil 6.10.7 Erweitern von Interfaces – Subinterfaces
Pfeil 6.10.8 Vererbte Konstanten bei Schnittstellen
Pfeil 6.10.9 Schnittstellenmethoden, die nicht implementiert werden müssen
Pfeil 6.10.10 Abstrakte Klassen und Schnittstellen im Vergleich
Pfeil 6.11 Geschachtelte (innere) Klassen, Schnittstellen, Aufzählungen
Pfeil 6.11.1 Statische innere Klassen und Schnittstellen
Pfeil 6.11.2 Mitglieds- oder Elementklassen
Pfeil 6.11.3 Lokale Klassen
Pfeil 6.11.4 Anonyme innere Klassen
Pfeil 6.11.5 this und Vererbung
Pfeil 6.12 Generische Datentypen
Pfeil 6.12.1 Einfache Klassenschablonen
Pfeil 6.12.2 Einfache Methodenschablonen
Pfeil 6.12.3 Umsetzen der Generics, Typlöschung und Raw-Types
Pfeil 6.12.4 Einschränken der Typen
Pfeil 6.12.5 Generics und Vererbung, Invarianz
Pfeil 6.12.6 Wildcards
Pfeil 6.13 Die Spezial-Oberklasse Enum
Pfeil 6.13.1 Methoden auf Enum-Objekten
Pfeil 6.13.2 enum mit eigenen Konstruktoren und Methoden
Pfeil 6.14 Dokumentationskommentare mit JavaDoc
Pfeil 6.14.1 Einen Dokumentationskommentar setzen
Pfeil 6.14.2 Mit javadoc eine Dokumentation erstellen
Pfeil 6.14.3 HTML-Tags in Dokumentationskommentaren
Pfeil 6.14.4 Generierte Dateien
Pfeil 6.14.5 Dokumentationskommentare im Überblick
Pfeil 6.14.6 JavaDoc und Doclets
Pfeil 6.14.7 Veraltete (deprecated) Klassen, Konstruktoren und Methoden

Das Gesetz ist der abstrakte Ausdruck des allgemeinen an und für sich seienden Willens. – Georg Wilhelm Friedrich Hegel

6 Eigene Klassen schreiben


Galileo Computing - Zum Seitenanfang

6.1 Eigene Klassen mit Eigenschaften deklarieren Zur nächsten ÜberschriftZur vorigen Überschrift

Die Deklaration einer Klasse leitet das Schlüsselwort class ein. Im Rumpf der Klasse lassen sich deklarieren:

  • Attribute (Variablen)
  • Methoden
  • Konstruktoren
  • Klassen- sowie Exemplar-Initialisierer
  • innere Klassen beziehungsweise innere Schnittstellen

Wir wollen die Konzepte der Klassen und Schnittstellen an einem kleinen Spiel verdeutlichen. Beginnen wir mit dem Spieler, den die Klasse Player repräsentieren soll.

Listing 6.1 com/tutego/insel/game/v1/Player.java, Player

class Player 
{ 
}

Die Klasse hat einen automatischen Konstruktor, sodass ein Exemplar unserer Klasse sich jetzt schon mit new Player() erzeugen ließe.


Galileo Computing - Zum Seitenanfang

6.1.1 Attribute deklarieren Zur nächsten ÜberschriftZur vorigen Überschrift

Diese Player-Klasse hat bisher keine Attribute und kann bisher nichts. Geben wir dem Spieler zwei Attribute: eines für den Namen und ein zweites für einen Gegenstand, den er trägt. Die Datentypen sollen beide String sein.

Listing 6.2 com/tutego/insel/game/v2/Player.java, Player

class Player 
{ 
  String name; 
  String item; 
}

Hinweis Hinweis Eine spezielle Namenskonvention für Objektvariablen gibt es nicht. So ist es zwar möglich, zur Unterscheidung von lokalen Variablen ein Präfix wie »f« oder »_« voranzustellen, doch sogar die Eclipse-Macher sind davon abgekommen. Objektvariablen können auch grundsätzlich wie Methoden heißen, doch ist das unüblich, da Variablennamen im Allgemeinen Substantive und Methoden Verben sind.


Eine zweite Klasse Playground erzeugt in der main()-Funktion für den mutigen Spieler ein Player-Objekt, schreibt und liest die Attribute.

Listing 6.3 com/tutego/insel/game/v2/Playground.java, Playground

class Playground 
{ 
  public static void main( String[] args ) 
  { 
    Player p = new Player(); 
    p.name = "Mutiger Manfred"; 
    p.item = "Schlips"; 
 
    System.out.printf( "%s nimmt einen %s mit.", p.name, p.item ); 
  } 
}

Initialisierung von Attributen

Anders als lokale Variablen initialisiert die Laufzeitumgebung alle Attribute mit einem Standardwert:

  • 0 bei numerischen Werten und char
  • false bei boolean
  • null bei Referenzvariablen

Gefällt uns das nicht, lassen sich die Variablen mit einem Wert belegen.

class Player 
{ 
  String name = ""; 
}

Galileo Computing - Zum Seitenanfang

6.1.2 Methoden deklarieren Zur nächsten ÜberschriftZur vorigen Überschrift

Zu Attributen gesellen sich Methoden, die üblicherweise auf den Objektvariablen arbeiten. Geben wir dem Player zwei Funktionen. Die erste Funktion clearName() soll den Namen zurück auf den Leerstring "" setzen. Die zweite Methode hasCompoundName() soll verraten, ob der Spielername aus einem Vor- und Nachnamen zusammengesetzt ist. Der Name »Parry Hotter« ist zum Beispiel zusammengesetzt, »Spuckiman« aber nicht.

Listing 6.4 com/tutego/insel/game/v3/Player.java, Player

class Player 
{ 
  String name = ""; 
  String item = ""; 
 
  void clearName() 
  { 
    name = ""; 
  } 
 
  boolean hasCompoundName() 
  { 
    return (name == null) ? false : name.contains( " " ); 
  } 
}

Testen wir die Methode mit zwei Spielern:

Listing 6.5 com/tutego/insel/game/v3/Playground.java, main()

Player parry = new Player(); 
parry.name = "Parry Hotter"; 
System.out.printf( "%s has compound name: %b%n", 
                   parry.name, parry.hasCompoundName() ); 
 
Player spucki = new Player(); 
spucki.name = "Spuckiman"; 
System.out.printf( "%s has compound name: %b%n", 
                   spucki.name, spucki.hasCompoundName() ); 
spucki.clearName(); 
System.out.printf( "Spuckis name is: '%s'%n", spucki.name );

Wie zu erwarten, ist aus Ausgabe:

Parry Hotter has compound name: true 
Spuckiman has compound name: false 
Spuckis name is: ''

Eclipse
Um schnell von einer Methode (oder Variablen) zur anderen zu navigieren, können Sie mit Keyboard Ctrl + Keyboard O ein Outline anzeigen (dieselbe Ansicht wie in der View Outline). Im Unterschied zur View lässt sich in diesem kleinen gelben Fenster mit den Cursor-Tasten navigieren, und ein Return befördert uns zur angewählten Funktion oder Variablen. Wird in der Ansicht erneut Keyboard Ctrl + Keyboard O gedrückt, befinden sich dort auch die in den Oberklassen deklarierten Eigenschaften. Sie sind grau, und zusätzlich befinden sich hinter den Eigenschaften die Klassennamen.

Methodenaufrufe und Nebeneffekte

Alle Variablen und Methoden einer Klasse sind in der Klasse selbst sichtbar. Das heißt: Innerhalb einer Klasse werden die Objektvariablen und Funktionen mit ihrem Namen verwendet. Somit greift die Funktion hasCompoundName() direkt auf das nötige Attribut name zu, um die Programmlogik auszuführen. Dies wird oft für Nebeneffekte (Seiteneffekte) genutzt. Die Methode clearName() ändert ausdrücklich eine Objektvariable und verändert so den Zustand des Objekts. hasCompoundName() liest dagegen nur den Zustand, modifiziert ihn aber nicht. Methoden, die Zustände ändern, sollten das in der API-Beschreibung entsprechend dokumentieren.


Galileo Computing - Zum Seitenanfang

6.1.3 Die this-Referenz topZur vorigen Überschrift

In jeder Objektmethode und jedem Konstruktor steht eine Referenz mit dem Namen this bereit, die auf das eigene Exemplar zeigt. Mit dieser this-Referenz lassen sich elegante Lösungen realisieren, wie die folgenden Beispiele zeigen:

  • Die this-Referenz löst das Problem, wenn lokale Variablen Objektvariablen verdecken.
  • Mit der this-Referenz lässt sich einer anderen Methode eine Referenz auf uns selbst geben.
  • Liefert eine Methode als Rückgabe die this-Referenz auf das aktuelle Objekt, lassen sich Methoden der Klasse einfach hintereinander setzen.

Beispiel Beispiel Die append()-Methoden bei StringBuilder liefern die this-Referenz, sodass sich Folgendes schreiben lässt:

StringBuilder sb = new StringBuilder(); 
sb.append( "Microsoft kauft Ebay" ).append( '?' );

Jedes append() liefert das StringBuilder-Objekt, auf dem es aufgerufen wird.


Kaskadierbare Methoden

Dem Player soll über zwei Methoden setName() und setItem() Name und Gegenstand gesetzt werden können. Beide Methoden liefern ihr eigenes Player-Objekt zurück.

Listing 6.6 com/tutego/insel/game/v4/Player.java, Player

class Player 
{ 
  String name = ""; 
  String item = ""; 
 
  Player setName( String n ) 
  { 
    name = n; 
    return this; 
  } 
 
  Player setItem( String i ) 
  { 
    item = i; 
    return this; 
  } 
 
  String id() 
  { 
    return name + " has " + item; 
  } 
}

Erzeugen wir einen Player, und kaskadieren wir drei Methoden:

Listing 6.7 com/tutego/insel/game/v4/Playground.java, main()

String s = new Player().setName( "Parry" ).setItem( "helmet" ).id(); 
System.out.println( s );                         // Parry has helmet

Der Ausdruck new Player() liefert eine Referenz, die wir sofort für den Methodenaufruf nutzen. Da setName() wiederum eine Objektreferenz vom Typ Person liefert, ist setItem() möglich. Die Verschachtelung von setName().setItem() bewirkt, dass Name und Gegenstand gesetzt wird und der nächste Methodenaufruf in der Kette über this eine Referenz auf dasselbe Objekt, aber mit verändertem internen Zustand bekommt. Der abschließende Aufruf von id() unterbricht die Kette, weil die Methode ein String zurückgibt.


Hinweis Hinweis Bei Anfragemethoden könnten wir versucht sein, diese praktische Eigenschaft überall zu verwenden. Allerdings sollten Objekte ihre Eigenschaften nach der JavaBeans-Konvention mit setXXX() setzen und ausdrücklich keine Rückgabe liefern. Eine mit dem Objekttyp deklarierte Rückgabe verstößt also gegen diese Konvention.


Überdeckte Objektvariablen nutzen

Hat eine lokale Variable den gleichen Namen wie eine Objektvariable, so verdeckt sie diese. Das heißt aber nicht, dass auf die äußere Variable nicht mehr zugegriffen werden kann. Die this-Referenz kann auf das aktuelle Objekt zugreifen und entsprechend mit dem Punkt-Operator auf einzelne Variablen des Objekts. Häufiger Einsatzort sind Parameter, die genauso genannt werden wie die Exemplarvariablen, um damit eine starke Zugehörigkeit auszudrücken.

Schreiben wir dazu die Methode setName() um:

String name;                     // Objektvariable name 
 
Player setName( String name )    // Lokale Parametervariable name 
{ 
  this.name = name; 
  return this; 
}

Der an setName() übergebene Wert soll die Objektvariable name initialisieren. Genau dann, wenn eine lokale Variable deklariert wird und sie eine Objekt- oder Klassenvariable überlagert, wird beim Zugriff die lokale Variable genutzt. Also würde im Rumpf der Methode eine Zuweisung wie name = "" die lokale Variable, also den aktuellen Parameterwert überschreiben. Erst mit this.name greifen wir auf die Objektvariable direkt zu, sodass this.name = name; die Objektvariable korrekt mit dem Argument initialisiert.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück



Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de