Rheinwerk Computing < openbook >


 
Inhaltsverzeichnis
Materialien zum Buch
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Arrays und ihre Anwendungen
5 Der Umgang mit Zeichen und Zeichenketten
6 Eigene Klassen schreiben
7 Objektorientierte Beziehungsfragen
8 Schnittstellen, Aufzählungen, versiegelte Klassen, Records
9 Ausnahmen müssen sein
10 Geschachtelte Typen
11 Besondere Typen der Java SE
12 Generics<T>
13 Lambda-Ausdrücke und funktionale Programmierung
14 Architektur, Design und angewandte Objektorientierung
15 Java Platform Module System
16 Die Klassenbibliothek
17 Einführung in die nebenläufige Programmierung
18 Einführung in Datenstrukturen und Algorithmen
19 Einführung in grafische Oberflächen
20 Einführung in Dateien und Datenströme
21 Einführung ins Datenbankmanagement mit JDBC
22 Bits und Bytes, Mathematisches und Geld
23 Testen mit JUnit
24 Die Werkzeuge des JDK
A Java SE-Module und Paketübersicht
Stichwortverzeichnis


Buch bestellen
Ihre Meinung?



Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom

Einführung, Ausbildung, Praxis
Buch: Java ist auch eine Insel


Java ist auch eine Insel

Pfeil 6 Eigene Klassen schreiben
Pfeil 6.1 Eigene Klassen mit Eigenschaften deklarieren
Pfeil 6.1.1 Objektvariablen deklarieren
Pfeil 6.1.2 Methoden deklarieren
Pfeil 6.1.3 Verdeckte (shadowed) Variablen
Pfeil 6.1.4 Die this-Referenz
Pfeil 6.2 Privatsphäre und Sichtbarkeit
Pfeil 6.2.1 Für die Öffentlichkeit: public
Pfeil 6.2.2 Kein Public Viewing – Passwörter sind privat
Pfeil 6.2.3 Wieso nicht freie Methoden und Variablen für alle?
Pfeil 6.2.4 Privat ist nicht ganz privat: Es kommt darauf an, wer’s sieht *
Pfeil 6.2.5 Zugriffsmethoden für Objektvariablen deklarieren
Pfeil 6.2.6 Setter und Getter nach der JavaBeans-Spezifikation
Pfeil 6.2.7 Paketsichtbar
Pfeil 6.2.8 Zusammenfassung zur Sichtbarkeit
Pfeil 6.3 Eine für alle – statische Methoden und Klassenvariablen
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 Variablen zum Datenaustausch *
Pfeil 6.3.6 Statische Eigenschaften und Objekteigenschaften *
Pfeil 6.4 Konstanten und Aufzählungen
Pfeil 6.4.1 Konstanten über statische finale Variablen
Pfeil 6.4.2 Typunsichere Aufzählungen
Pfeil 6.4.3 Aufzählungstypen: typsichere Aufzählungen mit enum
Pfeil 6.5 Objekte anlegen und zerstören
Pfeil 6.5.1 Konstruktoren schreiben
Pfeil 6.5.2 Verwandtschaft von Methode und Konstruktor
Pfeil 6.5.3 Der Standard-Konstruktor (default constructor)
Pfeil 6.5.4 Parametrisierte und überladene Konstruktoren
Pfeil 6.5.5 Copy-Konstruktor
Pfeil 6.5.6 Einen anderen Konstruktor der gleichen Klasse mit this(…) aufrufen
Pfeil 6.5.7 Immutable-Objekte und Wither-Methoden
Pfeil 6.5.8 Ihr fehlt uns nicht – der Garbage-Collector
Pfeil 6.6 Klassen- und Objektinitialisierung *
Pfeil 6.6.1 Initialisierung von Objektvariablen
Pfeil 6.6.2 Statische Blöcke als Klasseninitialisierer
Pfeil 6.6.3 Initialisierung von Klassenvariablen
Pfeil 6.6.4 Eincompilierte Belegungen der Klassenvariablen
Pfeil 6.6.5 Exemplarinitialisierer (Instanzinitialisierer)
Pfeil 6.6.6 Finale Werte im Konstruktor und in statischen Blöcken setzen
Pfeil 6.7 Zum Weiterlesen
 

Zum Seitenanfang

6    Eigene Klassen schreiben Zur vorigen ÜberschriftZur nächsten Überschrift

»Das Gesetz ist der abstrakte Ausdruck des allgemeinen an und für sich seienden Willens.«

– Georg Wilhelm Friedrich Hegel (1770–1831)

In den letzten Kapiteln haben wir viel über Objektorientierung erfahren, aber eher von der Benutzerseite her. Wir haben gesehen, wie Objekte aufgebaut werden, und auch einfache Klassen mit statischen Methoden haben wir implementiert. Es wird Zeit, das Wissen um alle objektorientierten Konzepte zu vervollständigen und eigene benutzerdefinierte Datentypen aufzubauen.

[»]  Hinweis

Wir wollen die Konzepte der Objektorientierung an einem Programm verdeutlichen, das an das Spiel Drug Wars angelehnt ist. John Dell entwickelte das MS-DOS-Spiel Anfang der 1980er-Jahre, um das Kernprinzip der Wirtschaft zu zeigen: Günstig einkaufen und teuer verkaufen. Das Spiel lässt sich im Browser spielen, und so sind die Regeln leicht zu verstehen:

In unseren Beispielen wechseln wir von den harten Drogen zu weichen Drogen und nutzen Süßigkeiten. Nennen wir unser Spiel »Jawbreaker«.

 

Zum Seitenanfang

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

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

  • Objekt- und Klassenvariablen

  • Methoden

  • Konstruktoren

  • Klassen- sowie Exemplarinitialisierer

  • geschachtelte Klassen, Schnittstellen und Aufzählungen

Minimalklasse

Im Mittelpunkt steht eine Süßigkeit, die von der Klasse Candy repräsentiert wird:

Listing 6.1     src/main/java/com/tutego/insel/game/c/v1/Candy.java

package com.tutego.insel.game.c.v1

class Candy { }
Im UML-Diagramm ist die Klasse »Candy« nur eine umrandete Box.

Abbildung 6.1     Im UML-Diagramm ist die Klasse »Candy« nur eine umrandete Box.

inline image  Die Klasse hat einen vom Compiler generierten Konstruktor, und new Candy() erzeugt aus diesem Bauplan ein Exemplar. Details zum Konstruktor folgen in Abschnitt 6.5.3, »Der Standard-Konstruktor (default constructor)«. Auf Sichtbarkeitsmodifizierer (wie public) wollen wir erst einmal verzichten, wir setzen uns im späteren Abschnitt 6.2 damit intensiver auseinander.

[»]  Codeabkürzung

Wie auch in den vorangegangenen Kapiteln werden die package- und die import-Deklarationen im Codeausschnitt weggelassen. Wenn die Sichtbarkeit keine Rolle spielt, bleibt es bei der Paketsichtbarkeit, damit der Code ein wenig kürzer wird.

 

Zum Seitenanfang

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

Diese Klasse class Candy { } besitzt keine Objektvariablen und kann daher keine Zustände speichern. Geben wir der Süßigkeit drei Objektvariablen: eine für den Namen (Typ String), eine zweite für den Preis (Typ int) und eine dritte für die Anzahl der Süßigkeiten (Typ int).

Listing 6.2     src/main/java/com/tutego/insel/game/c/v2/Candy.java, Ausschnitt

class Candy {

String name;

int price;

int quantity;

}
[»]  Hinweis

Bei Objektvariablen ist kein var möglich, die Datentypen müssen angegeben sein.

Eine zweite Klasse, Application, erzeugt in der statischen main(…)-Methode zwei Exemplare einer Süßigkeit, beschreibt die Objektvariablen und liest sie aus:

Listing 6.3     src/main/java/com/tutego/insel/game/c/v2/Application.java, Ausschnitt

Candy lollipop = new Candy();

lollipop.name = "Lollipop";

lollipop.price = 12;

lollipop.quantity = 2;



Candy licorice = new Candy();

licorice.name = "Licorice";

licorice.price = 22;



System.out.printf( "%s, %d × %d = %d%n", // Lollipop, 2 × 12 = 24

lollipop.name, lollipop.quantity, lollipop.price,

lollipop.quantity * lollipop.price );

System.out.printf( "%s, %d × %d = %d%n", // Licorice, 0 × 22 = 0

licorice.name, licorice.quantity, licorice.price,

licorice.quantity * licorice.price );
Das UML-Klassendiagramm zeigt die Abhängigkeiten von »Application« und »Candy«.

Abbildung 6.2     Das UML-Klassendiagramm zeigt die Abhängigkeiten von »Application« und »Candy«.

Das UML-Objektdiagramm zeigt die zwei Candy-Instanzen.

Abbildung 6.3     Das UML-Objektdiagramm zeigt die zwei Candy-Instanzen.

inline image  Spätestens, wenn zwei Dateien im Editor offen sind, möchten Tastaturjunkies schnell zwischen den Editoren wechseln. Das geht in IntelliJ mit (Strg)+(_ÿ) und (Strg)+(ª)+(_ÿ).

[»]  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. Bezeichner können auch nicht so heißen wie Schlüsselwörter.

Initialisierung von Objektvariablen

Anders als lokale Variablen initialisiert die Laufzeitumgebung alle Objektvariablen – das Gleiche gilt für Klassenvariablen, die wir in Abschnitt 6.3 besprechen werden – 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 Candy {

String name;

int price;

int quantity = 1;

}

Der Ausdruck new Candy().quantity == 1 würde also true ergeben.

[+]  Designtipp

Es ist eine Gratwanderung, einfache Datentypen zu verwenden oder doch andere Objekte zu referenzieren. Wenn Candy den Preis speichert, wäre ein int (oder double) problematisch, da der Candy auch eine Validierung durchführen müsste, damit der Preis nie negativ wird; das ist jedoch nicht Aufgabe einer Süßigkeit! Die allgemeine OOP-Regel lautet: Setze bei Daten, die validiert werden müssen und vielleicht auch mit anderen Objektvariablen zusammenhängen, einen neuen Typ ein.

Gültigkeitsbereich, Sichtbarkeit und Lebensdauer

Lokale Variablen beginnen ihr Leben in dem Moment, in dem sie deklariert und initialisiert werden. Endet der Block, ist die lokale Variable nicht mehr gültig, und sie kann nicht mehr verwendet werden, da sie aus dem Sichtbarkeitsbereich verschwunden ist. Bei Objektvariablen ist das anders. Eine Objektvariable lebt ab dem Moment, in dem das Objekt mit new aufgebaut wurde, und sie lebt so lange, bis der Garbage-Collector das Objekt wegräumt. Sichtbar und gültig ist die Variable aber immer im gesamten Objekt und in allen Blöcken.[ 144 ](Das gilt nicht für statische Methoden und statische Initialisierungsblöcke, aber diese werden erst später vorgestellt. )

 

Zum Seitenanfang

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

Zu Objektvariablen gesellen sich Methoden, die üblicherweise auf den Objektvariablen arbeiten. Geben wir der Süßigkeit zwei Methoden:

  • totalPrice(): Ermittelt den Gesamtpreis als Produkt aus Anzahl und Preis.

  • resetQuantity(): Setzt die Anzahl auf 1 zurück.

Anders als unsere bisherigen statischen Methoden werden diese drei Methoden für Candy Objektmethoden sein, also nicht den Modifizierer static tragen.

Listing 6.4     src/main/java/com/tutego/insel/game/c/v3/Candy.java, Ausschnitt

class Candy {

String name;

int price;

int quantity = 1;



int totalPrice() {

return price * quantity;

}



void resetQuantity() {

quantity = 1;

}

}
Das UML-Klassendiagramm von »Candy« zeigt drei Objektvariablen und zwei Methoden.

Abbildung 6.4     Das UML-Klassendiagramm von »Candy« zeigt drei Objektvariablen und zwei Methoden.

Die Methode totalPrice() bildet das Produkt als Preis und Anzahl und liefert das Ergebnis zurück. resetQuantity() setzt die Produktanzahl auf 1 zurück.

Testen wir die Methoden mit einer Süßigkeit:

Listing 6.5     src/main/java/com/tutego/insel/game/c/v3/Application.java, Ausschnitt

Candy lollipop = new Candy();

lollipop.name = "Lollipop";

lollipop.price = 12;

lollipop.quantity = 2;

System.out.println( lollipop.totalPrice() ); // 24

lollipop.resetQuantity();

System.out.println( lollipop.totalPrice() ); // 12

inline image  Um schnell von einer Methode (oder Variablen) zur anderen zu navigieren, zeigt (Strg)+(O) ein Outline an (dieselbe Ansicht wie in der Ansicht Outline). Im Unterschied zur Ansicht Outline lässt sich in diesem kleinen gelben Fenster mit den Cursor-Tasten navigieren, und ein (¢) befördert uns zur angewählten Methode oder zur angewählten Objektvariablen. Wird in der Ansicht erneut (Strg)+(O) gedrückt, befinden sich dort auch die in den Oberklassen deklarierten Eigenschaften; sie sind grau. Zusätzlich befinden sich hinter den Eigenschaften die Klassennamen.

[+]  JVM-Interna *

Jedes Objekt hat eigene Objektzustände, aber nicht jedes Objekt hat auch noch einmal den Code für die Methoden doppelt, denn der Code ändert sich ja nicht für jedes Objekt. Intern ist es eher so, dass die Methoden nur einmal existieren und einen Verweis auf die Objektdaten bekommen, auf denen sie operieren können.

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 Methoden mit ihrem Namen verwendet. Somit greift die Methode totalPrice(…) direkt auf die nötigen Objektvariablen price und quantity zu, um die Programmlogik auszuführen. Dies wird oft für Nebeneffekte (Seiteneffekte) genutzt. Die Methode resetQuantity() ändert ausdrücklich die Objektvariable quantity und verändert so den Zustand des Objekts. totalPrice(…) liest dagegen nur den Zustand, modifiziert ihn aber nicht. Methoden, die Zustände ändern, sollten das in der API-Beschreibung entsprechend dokumentieren. Methoden, die Zustände ändern, heißen auch Mutatoren; Methoden, die lesen, heißen englisch accessor methods.

Objektorientierte und prozedurale Programmierung im Vergleich

Entwickler aus der prozeduralen Welt haben ein anderes Denkmodell verinnerlicht, sodass wir an dieser Stelle die Besonderheit der Objektorientierung noch einmal verdeutlichen wollen. Während in der guten objektorientierten Modellierung die Objekte immer gleichzeitig Zustand und Verhalten besitzen, gibt es in der prozeduralen Welt nur Speicherbereiche, die referenziert werden; Daten und Verhalten liegen hier nicht zusammen. Problematisch wird es, wenn die prozedurale Denkweise in Java-Programmen abgebildet wird. Dazu ein Beispiel: Die Klasse CandyData ist ein reiner Datencontainer für den Zustand, aber Verhalten wird hier nicht deklariert:

Listing 6.6     src/main/java/com/tutego/insel/nonoop/CandyData.java, Ausschnitt

class CandyData {

String name;

int price;

int quantity = 1;

}

Anstatt nun die Methoden ordentlich, wie in unserem ersten Beispiel, mit an die Klasse zu hängen, würde in der prozeduralen Welt ein Unterprogramm genau ein Datenobjekt bekommen und von diesem Zustände erfragen oder ändern:

Listing 6.7     src/main/java/com/tutego/insel/nonoop/CandyFunctions.java, Ausschnitt

class CandyFunctions {

static int totalPrice( CandyData candy ) {

return candy.price * candy.quantity;

}

}

Da die Unterprogramme nun nicht mehr an Objekte gebunden sind, können die Methoden statisch sein. Genauso falsch wären aber auch Methoden (egal, ob statisch oder nicht) in der Klasse CandyData, wenn sie ein CandyData-Objekt übergeben bekommen.

Beim Aufruf ist dieser nichtobjektorientierte Ansatz gut zu sehen. Setzen wir in Tabelle 6.1 links den falschen und rechts den korrekt objektorientiert modellierten Weg ein:

prozedural

objektorientiert

CandyData lollipop = new CandyData();

lollipop.price = 12;

int p = CandyFunctions.totalPrice( lollipop );
Candy lollipop = new Candy();

lollipop.price = 12;

int p = lollipop.totalPrice();

Tabelle 6.1     Gegenüberstellung von prozeduraler und objektorientierter Programmierung

Ein Indiz für eine problematische objektorientierte Modellierung ist also, wenn externen Methoden Objekte übergeben werden, anstatt die Methoden selbst an die Objekte zu setzen.

 

Zum Seitenanfang

6.1.3    Verdeckte (shadowed) Variablen Zur vorigen ÜberschriftZur nächsten Überschrift

Führt eine Methode eine neue Variable ein, so kann der gleiche Variablenname nicht noch einmal in einem inneren Block verwendet werden.

[zB]  Beispiel

Folgendes in einer main(…)-Methode führt zu einem Compilerfehler:

public static void main( String[] args ) {

int args = 1; // inline image Duplicate local variable args

}

Beim Verlassen eines Blocks ist der Variablenname jedoch wieder frei. Folgendes ist daher in Ordnung:

for ( int i = 0; i < 10; i++ )

System.out.println( i );

for ( int i = 0; i < 10; i++ )

System.out.println( i );

Grundsätzlich keine Probleme gibt es, wenn eine lokale Variable/Parametervariable genauso heißt wie eine Objektvariable. Wir sprechen in diesem Fall von einer verdeckten Variablen – im Englischen shadowed variable genannt.[ 145 ](https://docs.oracle.com/javase/specs/jls/se14/html/jls-6.html#jls-6.4) Der Compiler wird dann die lokale Variable nutzen und nicht mehr die Objektvariable.

[zB]  Beispiel

Die lokale Variable price in totalPrice() verdeckt die Objektvariable price:

class Candy {

int price;

int quantity = 1;



int totalPrice() {

int price = quantity;

price *= price * quantity;

return price;

}

}

Es gibt hier zwei Variablen price, allerdings bezieht sich jeder Zugriff auf price in der Methode automatisch auf die lokale Variable und nicht auf die Objektvariable.

Verdeckte Variablen sind praktisch, denn ohne so ein Konzept könnte eine neu eingefügte Objektvariable schnell viele Methoden kaputt machen, die zufälligerweise im Rumpf ebenfalls den gleichen Namen nutzen.[ 146 ](Fast alle Programmiersprachen besitzen verdeckte Variablen. Eine Ausnahme ist TypeScript. )

Doch was machen wir, wenn wir eine lokale Variable gleichzeitig mit einer Objektvariablen gleichen Namens nutzen wollen?

 

Zum Seitenanfang

6.1.4    Die this-Referenz Zur vorigen ÜberschriftZur nächsten Überschrift

In jeder Objektmethode und jedem Konstruktor[ 147 ](Sowie Exemplarinitialisierer, doch der Code landet im 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 Parameter oder lokale Variablen Objektvariablen verdecken.

  • Liefert eine Methode als Rückgabe die this-Referenz auf das aktuelle Objekt, lassen sich Methoden der Klasse einfach hintereinandersetzen.

  • Mit der this-Referenz lässt sich einer anderen Methode eine Referenz auf uns selbst geben.

Überdeckte Objektvariablen nutzen

Trägt eine lokale Variable den gleichen Namen wie eine Objektvariable, so verdeckt sie diese; das haben wir eben im vorherigen Abschnitt gesehen. Das ist so weit nicht tragisch und wird nur dann zum Problem, wenn später Zugriff auf die Objektvariable nötig ist.

Das heißt aber nicht, dass auf die Objektvariable nicht mehr zugegriffen werden kann. Die this-Referenz zeigt auf das aktuelle Objekt, und damit ist auch ein Zugriff auf Objekteigenschaften jederzeit möglich. Im folgenden Beispiel wird ebenfalls eine lokale Variable price eingeführt, doch Zugriff auf die Objektvariable gelingt über this.price:

Listing 6.8     src/main/java/com/tutego/insel/game/c/v4/Candy.java, Ausschnitt

class Candy {

int price;

int quantity = 1;



int totalPrice() {

int price = quantity * this.price;

return price;

}

}

this für Setter nutzen

Häufiger Einsatzort für das this sind Methoden oder Konstruktoren, die Zustände initialisieren. Gerne nennen Entwickler die Parametervariablen so wie die Exemplarvariablen, um damit eine starke Zugehörigkeit auszudrücken. Schreiben wir also eine Methode setName(String):

class Candy {

String name;



public void setName( String name ) {

this.name = name;

}

}

Das an setName(String) übergebene Objekt soll die Objektvariable name initialisieren. So greift this.name auf die Objektvariable direkt zu, sodass die Zuweisung this.name = name die Objektvariable mit dem Argument initialisiert.

this für kaskadierte Methoden *

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

StringBuilder sb = new StringBuilder();

sb.append( "Android oder iPhone" ).append( '?' );

Jedes append(…) liefert das StringBuilder-Objekt, auf dem es aufgerufen wird – wir können also Methoden kaskadiert anhängen oder es bleiben lassen.

Wir wollen diese Möglichkeit nutzen und eine andere Implementierung der Candy-Klasse programmieren, sodass die Methoden name(String) und price(int) Name und Preis zuweisen. Beide Methoden liefern ihr eigenes Candy-Objekt über die this-Referenz zurück:

Listing 6.9     src/main/java/com/tutego/insel/game/c/v5/Candy.java, Ausschnitt

class Candy {

String name;

int price;



Candy name( String name ) {

this.name = name;

return this;

}



String name() {

return name;

}



Candy price( int price ) {

this.price = price;

return this;

}



int price() {

return price;

}

}

Erzeugen wir ein Candy, und kaskadieren wir die Methoden:

Listing 6.10     src/main/java/com/tutego/insel/game/c/v5/Application.java, Ausschnitt

Candy candy = new Candy().name( "Nerds Candy" ).price( 80 );

System.out.printf( "%s %d%n", candy.name(), candy.price() ); // Nerds Candy 80
UML-Klassendiagramm für »Candy« mit Fluent-API

Abbildung 6.5     UML-Klassendiagramm für »Candy« mit Fluent-API

Der Ausdruck new Candy() liefert eine Referenz, die wir sofort für den Methodenaufruf nutzen. Da name(…) wiederum eine Objektreferenz vom Typ Candy liefert, ist dahinter direkt .price(…) möglich. Die Verschachtelung von name("Nerds Candy").price(80) bewirkt also, dass Name und Preis gesetzt werden und der jeweils nächste Methodenaufruf in der Kette über this eine Referenz auf dasselbe Objekt, aber mit verändertem internem Zustand bekommt.

Beispiele dieser Bauart sind in der Java-Bibliothek an einigen Stellen zu finden. Sie werden auch Builder genannt. Sie bestehen in der Regel nur aus den schreibenden Methoden.

[»]  Hinweis

Die Methode Candy name(String) ist mit ihrer Rückgabe praktisch, verstößt aber aus zwei Gründen gegen die JavaBeans-Konvention: Setter dürfen keine Rückgabe haben und müssen immer mit set beginnen. JavaBeans sind also nicht mit dieser kompakten Builder-Schreibweise »kompatibel«.

Sich selbst mit this übergeben

Möchte sich ein Objekt A einem anderen Objekt B mitteilen, damit B das andere Objekt A »kennt«, so funktioniert das gut mit der this-Referenz. Demonstrieren wir das an einem »Ich bin dein Vater«-Beispiel: Die zwei Klassen Luke und Darth repräsentieren zwei Personen, wobei Luke eine Objektvariable dad für seinen Vater hat:

Listing 6.11     src/main/java/com/tutego/insel/oop/LukeAndVader.java, Teil 1

class Luke {

Darth dad;

}



class Darth {

void revealTruthTo( Luke son ) {

son.dad = this;

}

}

Spannend ist die Methode revealTruthTo(Luke), denn sie setzt beim übergebenen Luke-Objekt die Objektvariable dad mit der this-Referenz. Damit kennt Luke seinen Vater, was in folgender Klasse getestet wird:

Listing 6.12     src/main/java/com/tutego/insel/oop/LukeAndVader.java, Teil 2

Luke luke = new Luke();

Darth vader = new Darth();

System.out.println( luke.dad ); // null

vader.revealTruthTo( luke );

System.out.println( luke.dad ); // com.tutego.insel.oop.Darth@01234567
[»]  Hinweis

In statischen Methoden steht die this-Referenz nicht zur Verfügung, da wir uns in Klassenmethoden nicht auf ein konkretes Objekt beziehen.

 


Ihre Meinung?

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java ist auch eine Insel Java ist auch eine Insel

Jetzt Buch bestellen


 Buchempfehlungen
Zum Rheinwerk-Shop: Captain CiaoCiao erobert Java

Captain CiaoCiao erobert Java




Zum Rheinwerk-Shop: Algorithmen in Java

Algorithmen in Java




Zum Rheinwerk-Shop: Spring Boot 3 und Spring Framework 6

Spring Boot 3 und Spring Framework 6




Zum Rheinwerk-Shop: Java SE 9 Standard-Bibliothek

Java SE 9 Standard-Bibliothek




 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und in die Schweiz

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2024

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.

 

[Rheinwerk Computing]



Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de



Cookie-Einstellungen ändern