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 3 Klassen und Objekte
Pfeil 3.1 Objektorientierte Programmierung (OOP)
Pfeil 3.1.1 Warum überhaupt OOP?
Pfeil 3.1.2 Denk ich an Java, denk ich an Wiederverwendbarkeit
Pfeil 3.2 Eigenschaften einer Klasse
Pfeil 3.2.1 Klassenarbeit mit Point
Pfeil 3.3 Natürlich modellieren mit der UML (Unified Modeling Language) *
Pfeil 3.3.1 Wichtige Diagrammtypen der UML *
Pfeil 3.4 Neue Objekte erzeugen
Pfeil 3.4.1 Ein Exemplar einer Klasse mit dem Schlüsselwort new anlegen
Pfeil 3.4.2 Deklarieren von Referenzvariablen
Pfeil 3.4.3 Jetzt mach mal ’nen Punkt: Zugriff auf Objektvariablen und -methoden
Pfeil 3.4.4 Der Zusammenhang von new, Heap und Garbage-Collector
Pfeil 3.4.5 Überblick über Point-Methoden
Pfeil 3.4.6 Konstruktoren nutzen
Pfeil 3.5 ZZZZZnake
Pfeil 3.6 Pakete schnüren, Importe und Compilationseinheiten
Pfeil 3.6.1 Java-Pakete
Pfeil 3.6.2 Pakete der Standardbibliothek
Pfeil 3.6.3 Volle Qualifizierung und import-Deklaration
Pfeil 3.6.4 Mit import p1.p2.* alle Typen eines Pakets erreichen
Pfeil 3.6.5 Hierarchische Strukturen über Pakete und die Spiegelung im Dateisystem
Pfeil 3.6.6 Die package-Deklaration
Pfeil 3.6.7 Unbenanntes Paket (default package)
Pfeil 3.6.8 Compilationseinheit (Compilation Unit)
Pfeil 3.6.9 Statischer Import *
Pfeil 3.7 Mit Referenzen arbeiten, Vielfalt, Identität, Gleichwertigkeit
Pfeil 3.7.1 null-Referenz und die Frage der Philosophie
Pfeil 3.7.2 Alles auf null? Referenzen testen
Pfeil 3.7.3 Zuweisungen bei Referenzen
Pfeil 3.7.4 Methoden mit Referenztypen als Parameter
Pfeil 3.7.5 Identität von Objekten
Pfeil 3.7.6 Gleichwertigkeit und die Methode equals(…)
Pfeil 3.8 Zum Weiterlesen
 

Zum Seitenanfang

3.4    Neue Objekte erzeugen Zur vorigen ÜberschriftZur nächsten Überschrift

Eine Klasse beschreibt also, wie ein Objekt aussehen soll. In einer Mengen- bzw. Elementbeziehung ausgedrückt, entsprechen Objekte den Elementen und Klassen den Mengen, in denen die Objekte als Elemente enthalten sind. Diese Objekte haben Eigenschaften, die sich nutzen lassen. Wenn ein Punkt Koordinaten repräsentiert, wird es Möglichkeiten geben, diese Zustände zu erfragen und zu ändern.

Im Folgenden wollen wir untersuchen, wie sich von der Klasse Point zur Laufzeit Exemplare erzeugen lassen und wie der Zugriff auf die Eigenschaften der Point-Objekte aussieht.

 

Zum Seitenanfang

3.4.1    Ein Exemplar einer Klasse mit dem Schlüsselwort new anlegen Zur vorigen ÜberschriftZur nächsten Überschrift

Objekte müssen in Java immer ausdrücklich erzeugt werden. Dazu definiert die Sprache das Schlüsselwort new.

[zB]  Beispiel

Anlegen eines Punkt-Objekts:

new java.awt.Point();

Im Grunde ist new so etwas wie ein unärer Operator. Hinter dem Schlüsselwort new folgt der Name der Klasse, von der ein Exemplar erzeugt werden soll. Der Klassenname ist hier voll qualifiziert angegeben, da sich Point in einem Paket java.awt befindet. (Ein Paket ist eine Gruppe zusammengehöriger Klassen; wir werden in Abschnitt 3.6.3, »Volle Qualifizierung und import-Deklaration«, sehen, dass Entwickler diese Schreibweise auch abkürzen können.) Hinter dem Klassennamen folgt ein Paar runder Klammern für den Konstruktoraufruf. Dieser ist eine Art Methodenaufruf, über den sich Werte für die Initialisierung des frischen Objekts übergeben lassen.

Konnte die Speicherverwaltung von Java für das anzulegende Objekt freien Speicher reservieren und konnte der Konstruktor gültig durchlaufen werden, gibt der new-Ausdruck anschließend eine Referenz auf das frische Objekt an das Programm zurück. Merken wir uns diese Referenz nicht, kann die automatische Speicherbereinigung das Objekt wieder freigeben.

 

Zum Seitenanfang

3.4.2    Deklarieren von Referenzvariablen Zur vorigen ÜberschriftZur nächsten Überschrift

Das Ergebnis eines new ist eine Referenz auf das neue Objekt. Die Referenz wird in der Regel in einer Referenzvariablen zwischengespeichert, um fortlaufende Eigenschaften des Objekts nutzen zu können.

[zB]  Beispiel

Deklariere die Variable p vom Typ java.awt.Point. Die Variable p nimmt anschließend die Referenz von dem neuen Objekt auf, das mit new angelegt wurde.

java.awt.Point p;

p = new java.awt.Point();

Die Deklaration und die Initialisierung einer Referenzvariablen lassen sich kombinieren (auch eine lokale Referenzvariable ist wie eine lokale Variable primitiven Typs zu Beginn uninitialisiert):

java.awt.Point p = new java.awt.Point();

Die Typen müssen natürlich kompatibel sein, und ein Punkt-Objekt geht nicht als String durch. Der Versuch, ein Punkt-Objekt einer int- oder String-Variablen zuzuweisen, ergibt somit einen Compilerfehler:

int    p = new java.awt.Point(); // inline image Type mismatch: cannot convert from

// Point to int

String s = new java.awt.Point(); // inline image Type mismatch: cannot convert from

// Point to String

Damit speichert eine Variable entweder einen einfachen Wert (Variable vom Typ int, boolean, double …) oder einen Verweis auf ein Objekt. Der Verweis ist letztendlich intern ein Pointer auf einen Speicherbereich, doch der ist für Java-Entwickler so nicht sichtbar.

Referenztypen gibt es in vier Ausführungen: Klassentypen, Schnittstellentypen (auch Interface-Typen genannt), Array-Typen (auch Feldtypen genannt) und Typvariablen (eine Spezialität von generischen Typen). In unserem Fall haben wir ein Beispiel für einen Klassentyp.

Die Tastenkombination (Strg)+(1) ermöglicht es, entweder eine neue lokale Variable oder eine Objektvariable für den Ausdruck anzulegen.

Abbildung 3.2     Die Tastenkombination (Strg)+(1) ermöglicht es, entweder eine neue lokale Variable oder eine Objektvariable für den Ausdruck anzulegen.

 

Zum Seitenanfang

3.4.3    Jetzt mach mal ’nen Punkt: Zugriff auf Objektvariablen und -methoden Zur vorigen ÜberschriftZur nächsten Überschrift

Die in einer Klasse deklarierten Variablen heißen Objektvariablen bzw. Exemplar-, Instanz- oder Ausprägungsvariablen. Jedes erzeugte Objekt hat seinen eigenen Satz von Objektvariablen:[ 108 ](Es gibt auch den Fall, dass sich mehrere Objekte eine Variable teilen, sogenannte statische Variablen. Diesen Fall werden wir später in Kapitel 6, »Eigene Klassen schreiben«, genauer betrachten. ) Sie bilden den Zustand des Objekts.

Der Punkt-Operator . erlaubt auf Objekten den Zugriff auf die Zustände oder den Aufruf von Methoden. Der Punkt steht zwischen einem Ausdruck, der eine Referenz liefert, und der Objekteigenschaft. Welche Eigenschaften eine Klasse genau bietet, zeigt die API-Dokumentation – wenn ein Objekt eine Eigenschaft nicht hat, wird der Compiler eine Nutzung verbieten.

[zB]  Beispiel

Die Variable p referenziert ein java.awt.Point-Objekt. Die Objektvariablen x und y sollen initialisiert werden:

java.awt.Point p = new java.awt.Point();

p.x = 1;

p.y = 2 + p.x;

Ein Methodenaufruf gestaltet sich genauso einfach wie ein Zugriff auf Klassen- oder Objektvariablen. Hinter dem Ausdruck mit der Referenz folgt nach dem Punkt der Methodenname.

Die Tastenkombination (Strg) + Leertaste zeigt an, welche Eigenschaften eine Referenz ermöglicht. Eine Auswahl mit der (¢)-Taste wählt die Eigenschaft aus und setzt insbesondere bei Methoden den Cursor zwischen das Klammerpaar.

Abbildung 3.3     Die Tastenkombination (Strg) + Leertaste zeigt an, welche Eigenschaften eine Referenz ermöglicht. Eine Auswahl mit der (¢)-Taste wählt die Eigenschaft aus und setzt insbesondere bei Methoden den Cursor zwischen das Klammerpaar.

Tür und Spieler auf dem Spielbrett

Punkt-Objekte erscheinen auf den ersten Blick als mathematische Konstrukte, doch sie sind allgemein nutzbar. Alles, was eine Position im zweidimensionalen Raum hat, lässt sich gut durch ein Punkt-Objekt repräsentieren. Der Punkt speichert für uns ja x und y, und hätten wir keine Punkt-Objekte, so müssten wir x und y immer extra speichern.

Nehmen wir an, wir wollen einen Spieler und eine Tür auf ein Spielbrett setzen. Natürlich haben die beiden Objekte Positionen. Ohne Objekte würde eine Speicherung der Koordinaten vielleicht so aussehen:

int playerX;

int playerY;

int doorX;

int doorY;

Die Modellierung ist nicht optimal, da wir mit der Klasse Point eine viel bessere Abstraktion haben, die zudem hübsche Methoden anbietet.

ohne Abstraktion, nur die nackten Daten

Kapselung der Zustände in ein Objekt

int playerX;

int playerY;

java.awt.Point player;

int doorX;

int doorY;

java.awt.Point door;

Tabelle 3.2     Objekte kapseln Zustände.

Das folgende Beispiel erzeugt zwei Punkte, die die x/y-Koordinate eines Spielers und einer Tür auf einem Spielbrett repräsentieren. Nachdem die Punkte erzeugt wurden, werden die Koordinaten gesetzt, und es wird außerdem getestet, wie weit der Spieler und die Tür voneinander entfernt sind:

Listing 3.1     PlayerAndDoorAsPoints.java

class PlayerAndDoorAsPoints {



public static void main( String[] args ) {

java.awt.Point player = new java.awt.Point();

player.x = player.y = 10;



java.awt.Point door = new java.awt.Point();

door.setLocation( 10, 100 );



System.out.println( player.distance( door ) ); // 90.0

}

}

Im ersten Fall belegen wir die Variablen x, y des Spiels explizit. Im zweiten Fall setzen wir nicht direkt die Objektzustände über die Variablen, sondern verändern die Zustände über die Methode setLocation(…). Die beiden Objekte besitzen eigene Koordinaten und kommen sich nicht in die Quere.

Die Abhängigkeit zwischen einer Klasse und dem »java.awt.Point« zeigt das UML-Diagramm mit einer gestrichelten Linie an. Attribute und Operationen von »Point« sind nicht dargestellt.

Abbildung 3.4     Die Abhängigkeit zwischen einer Klasse und dem »java.awt.Point« zeigt das UML-Diagramm mit einer gestrichelten Linie an. Attribute und Operationen von »Point« sind nicht dargestellt.

toString()

Die Methode toString() liefert als Ergebnis ein String-Objekt, das den Zustand des Punktes preisgibt. Sie ist insofern besonders, als es immer auf jedem Objekt eine toString()-Methode gibt – nicht in jedem Fall ist die Ausgabe allerdings sinnvoll.

Listing 3.2     PointToStringDemo.java

class PointToStringDemo {



public static void main( String[] args ) {

java.awt.Point player = new java.awt.Point();

java.awt.Point door = new java.awt.Point();

door.setLocation( 10, 100 );



System.out.println( player.toString() ); // java.awt.Point[x=0,y=0]

System.out.println( door ); // java.awt.Point[x=10,y=100]

}

}
[+]  Tipp

Anstatt für die Ausgabe explizit println(obj.toString()) aufzurufen, funktioniert auch ein println(obj). Das liegt daran, dass die Signatur println(Object) jedes beliebige Objekt als Argument akzeptiert und auf diesem Objekt automatisch die toString()-Methode aufruft.

Nach dem Punkt geht’s weiter

Die Methode toString() liefert, wie wir gesehen haben, als Ergebnis ein String-Objekt:

java.awt.Point  p = new java.awt.Point();

String s = p.toString();

System.out.println( s ); // java.awt.Point[x=0,y=0]

Das String-Objekt besitzt selbst wieder Methoden. Eine davon ist length(), die die Länge der Zeichenkette liefert:

System.out.println( s.length() );              // 23

Das Erfragen des String-Objekts und seiner Länge können wir zu einer Anweisung verbinden; wir sprechen von kaskadierten Aufrufen.

java.awt.Point  p = new java.awt.Point();

System.out.println( p.toString().length() ); // 23

Objekterzeugung ohne Variablenzuweisung

Bei der Nutzung von Objekteigenschaften muss der Typ links vom Punkt immer eine Referenz sein. Ob die Referenz nun aus einer Variablen kommt oder on-the-fly erzeugt wird, ist egal. Damit folgt, dass

java.awt.Point  p = new java.awt.Point();

System.out.println( p.toString().length() ); // 23

genau das Gleiche bewirkt wie:

System.out.println( new java.awt.Point().toString().length() ); // 23
Jede Schachtelung ergibt einen neuen Typ.

Abbildung 3.5     Jede Schachtelung ergibt einen neuen Typ.

Im Prinzip funktioniert auch Folgendes:

new java.awt.Point().x = 1;

Dies ist hier allerdings unsinnig, da zwar das Objekt erzeugt und eine Objektvariable gesetzt wird, anschließend das Objekt aber für die automatische Speicherbereinigung wieder Freiwild ist.

[zB]  Beispiel

Finde über ein File-Objekt heraus, wie groß eine Datei ist:

long size = new java.io.File( "file.txt" ).length();

Die Rückgabe der File-Methode length() ist die Länge der Datei in Bytes.

 

Zum Seitenanfang

3.4.4    Der Zusammenhang von new, Heap und Garbage-Collector Zur vorigen ÜberschriftZur nächsten Überschrift

Bekommt das Laufzeitsystem die Anfrage, ein Objekt mit new zu erzeugen, so reserviert es so viel Speicher, dass alle Objekteigenschaften und Verwaltungsinformationen dort Platz finden. Ein Point-Objekt speichert die Koordinaten in zwei int-Werten, also sind mindestens 2 mal 4 Byte nötig. Den Speicherplatz nimmt die Laufzeitumgebung vom Heap. Der Heap wächst von einer Startgröße bis hin zu einer erlaubten Maximalgröße, damit ein Java-Programm nicht beliebig viel Speicher vom Betriebssystem abgreifen kann, was die Maschine möglicherweise in den Ruin treibt. In der HotSpot JVM ist der Heap zum Start 1/64 des Hauptspeichers groß und wächst dann bis zur maximalen Größe von 1/4 des Hautspeichers.[ 109 ](https://docs.oracle.com/en/java/javase/17/gctuning/ergonomics.html)

[»]  Hinweis

Es gibt in Java nur wenige Sonderfälle, in denen neue Objekte nicht über new angelegt werden. So erzeugt die auf nativem Code basierende Methode newInstance() vom Constructor-Objekt ein neues Objekt. Auch clone() kann ein neues Objekt als Kopie eines anderen Objekts erzeugen. Bei der String-Konkatenation mit + ist für uns zwar kein new zu sehen, doch der Compiler wird Anweisungen bauen, um das neue String-Objekt anzulegen.

Ist das System nicht in der Lage, genügend Speicher für ein neues Objekt bereitzustellen, versucht die automatische Speicherbereinigung in einer letzten Rettungsaktion, alles Ungebrauchte wegzuräumen. Ist dann immer noch nicht ausreichend Speicher frei, generiert die Laufzeitumgebung einen OutOfMemoryError und beendet das gesamte Programm.[ 110 ](Diese besondere Ausnahme kann aber auch abgefangen werden. Das ist für den Serverbetrieb wichtig, denn wenn ein Puffer zum Beispiel nicht erzeugt werden kann, soll nicht gleich die ganze JVM stoppen. )

Heap und Stack

Die JVM-Spezifikation sieht für Daten fünf verschiedene Speicherbereiche (engl. runtime data areas) vor.[ 111 ](§ 2.5 der JVM-Spezifikation, https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-2.html#jvms-2.5) Neben dem Heap-Speicher wollen wir uns den Stack-Speicher (Stapelspeicher) kurz anschauen. Den nutzt die Java-Laufzeitumgebung zum Beispiel für lokale Variablen. Auch verwendet Java den Stack beim Methodenaufruf mit Parametern. Die Argumente kommen vor dem Methodenaufruf auf den Stapel, und die aufgerufene Methode kann über den Stack auf die Werte lesend oder schreibend zugreifen. Bei endlosen rekursiven Methodenaufrufen ist irgendwann die maximale Stack-Größe erreicht, und es kommt zu einer Exception vom Typ java.lang.StackOverflowError. Da mit jedem Thread ein JVM-Stack assoziiert ist, bedeutet das das Ende des Threads, wobei andere Threads unbeeindruckt weiterlaufen.

Automatische Speicherbereinigung/Garbage-Collector (GC) – es ist dann mal weg

Nehmen wir folgendes Szenario an:

java.awt.Point binariumLocation;

binariumLocation = new java.awt.Point( 50, 9 );

binariumLocation = new java.awt.Point( 51, 7 );

Wir deklarieren eine Point-Variable, bauen ein Exemplar auf und belegten die Variable. Dann bauen wir ein neues Point-Objekt auf und überschreiben die Variable. Doch was ist mit dem ersten Punkt?

Wird das Objekt nicht mehr vom Programm referenziert, so bemerkt dies die automatische Speicherbereinigung alias der Garbage-Collector (GC) und gibt den reservierten Speicher wieder frei.[ 112 ](Mit dem gesetzten java-Schalter -verbose:gc gibt es immer Konsolenausgaben, wenn der GC nicht mehr referenzierte Objekte erkennt und wegräumt. ) Die automatische Speicherbereinigung testet dazu regelmäßig, ob die Objekte auf dem Heap noch benötigt werden. Werden sie nicht benötigt, löscht der Objektjäger sie. Es weht also immer ein Hauch von Friedhof über dem Heap, und nachdem die letzte Referenz vom Objekt genommen wird, ist es auch schon tot. Es gibt verschiedene GC-Algorithmen, und jeder Hersteller einer JVM hat eigene Verfahren.

 

Zum Seitenanfang

3.4.5    Überblick über Point-Methoden Zur vorigen ÜberschriftZur nächsten Überschrift

Ein paar Methoden der Klasse Point kamen schon vor, und die API-Dokumentation zählt selbstverständlich alle Methoden auf. Die interessanteren sind:

class java.awt.Point
  • double getX()

  • double getY()

    Liefert die x- bzw. y-Koordinate.

  • void setLocation(double x, double y)

    Setzt gleichzeitig die x- und die y-Koordinate. Die Koordinaten werden gerundet und in Ganzzahlen gespeichert.

  • boolean equals(Object obj)

    Prüft, ob ein anderer Punkt die gleichen Koordinaten besitzt. Dann ist die Rückgabe true, sonst false. Wird etwas anderes als ein Point übergeben, so wird der Compiler das nicht bemäkeln, nur wird das Ergebnis dann immer false sein.

Vererbungshierarchie bei Point2D

Abbildung 3.6     Vererbungshierarchie bei Point2D

[»]  Hinweis

Es ist überraschend, dass ein Point die Koordinaten als int speichert, aber die Methoden getX() und getY() ein double liefern und setLocation(double, double)die Koordinaten als double annimmt, rundet und als int ablegt, also Genauigkeit verliert. Der Grund hat etwas mit Vererbung zu tun, was in Kapitel 7 ausführlicher beleuchtet wird. Point erbt von Point2D, und dort gibt es schon double getX(), double getY() und setLocation(double, double); die Unterklasse Point kann nicht einfach aus double ein int machen.

Ein paar Worte über Vererbung und die API-Dokumentation *

Eine Klasse besitzt nicht nur eigene Eigenschaften, sondern erbt auch immer welche von ihren Eltern. Im Fall von Point ist die Oberklasse Point2D – so sagt es die API-Dokumentation. Selbst Point2D erbt von Object, einer magischen Klasse, die alle Java-Klassen als Oberklasse haben. Der Vererbung widmen wir später ein sehr ausführliches Kapitel 7, »Objektorientierte Beziehungsfragen«, aber es ist jetzt schon wichtig zu verstehen, dass die Oberklasse Objektvariablen und Methoden an Unterklassen weitergibt. Sie sind in der API-Dokumentation einer Klasse nur kurz im Block »Methods inherited from …« aufgeführt und gehen schnell unter. Für Entwickler ist es unabdingbar, nicht nur bei den Methoden der Klasse selbst zu schauen, sondern auch bei den geerbten Methoden. Bei Point sind es also nicht nur die Methoden dort selbst, sondern auch die Methoden aus Point2D und Object.

Nehmen wir uns einige Methoden der Oberklasse vor. Die Klassendeklaration von Point enthält ein extends Point2D, was explizit klarmacht, dass es eine Oberklasse gibt:[ 113 ](Damit ist die Klassendeklaration noch nicht vollständig, da ein implements Serializable fehlt, doch das soll uns jetzt erst einmal egal sein. )

class java.awt.Point

extends Point2D
  • static double distance(double x1, double y1, double x2, double y2)

    Berechnet den Abstand zwischen den gegebenen Punkten nach der euklidischen Distanz.

  • double distance(double x, double y)

    Berechnet den Abstand des aktuellen Punktes zu angegebenen Koordinaten.

  • double distance(Point2D pt)

    Berechnet den Abstand des aktuellen Punktes zu den Koordinaten des übergebenen Punktes.

Sind zwei Punkte gleich?

Ob zwei Punkte gleich sind, sagt uns die equals(…)-Methode. Die Anwendung ist einfach. Stellen wir uns vor, wir wollen Koordinaten für einen Spieler, eine Tür und eine Schlange verwalten und dann testen, ob der Spieler »auf« der Tür steht und die Schlange auf der Position des Spielers:

Listing 3.3     PointEqualsDemo.java

class PointEqualsDemo {



public static void main( String[] args ) {

java.awt.Point player = new java.awt.Point();

player.x = player.y = 10;



java.awt.Point door = new java.awt.Point();

door.setLocation( 10, 10 );



System.out.println( player.equals( door ) ); // true

System.out.println( door.equals( player ) ); // true



java.awt.Point snake = new java.awt.Point();

snake.setLocation( 20, 22 );



System.out.println( snake.equals( door ) ); // false

}

}

Da Spieler und Tür die gleichen Koordinaten besitzen, liefert equals(…) die Rückgabe true. Ob wir den Abstand vom Spieler zur Tür berechnen lassen oder den Abstand von der Tür zum Spieler – das Ergebnis bei equals(…) sollte immer symmetrisch sein.

Eine andere Testmöglichkeit ergibt sich durch distance(…), denn ist der Abstand der Punkte null, so liegen die Punkte natürlich aufeinander und haben keinen Abstand.

Listing 3.4     Distances.java

class Distances {



public static void main( String[] args ) {

java.awt.Point player = new java.awt.Point();

player.setLocation( 10, 10 );

java.awt.Point door = new java.awt.Point();

door.setLocation( 10, 10 );

java.awt.Point snake = new java.awt.Point();

snake.setLocation( 20, 10 );



System.out.println( player.distance( door ) ); // 0.0

System.out.println( player.distance( snake ) ); // 10.0

System.out.println( player.distance( snake.x, snake.y ) ); // 10.0

}

}

Spieler, Tür und Schlange sind wieder als Point-Objekte repräsentiert und mit Positionen vorbelegt. Beim player rufen wir die Methode distance(…) auf und übergeben den Verweis auf die Tür und die Schlange.

 

Zum Seitenanfang

3.4.6    Konstruktoren nutzen Zur vorigen ÜberschriftZur nächsten Überschrift

Werden Objekte mit new angelegt, so wird ein Konstruktor aufgerufen. Ein Konstruktor hat die Aufgabe, ein Objekt in einen Startzustand zu versetzen, zum Beispiel die Objektvariablen zu initialisieren. Ein Konstruktor ist dazu ein guter Weg, denn er wird immer als Erstes aufgerufen, noch bevor eine andere Methode aufgerufen wird. Die Initialisierung im Konstruktor stellt sicher, dass das neue Objekt einen sinnvollen Anfangszustand aufweist.

Aus der API-Dokumentation von Point sind drei Konstruktoren abzulesen:

class java.awt.Point

extends Point2D
  • Point()

    Legt einen Punkt mit den Koordinaten (0, 0) an.

  • Point(int x, int y)

    Legt einen neuen Punkt an und initialisiert ihn mit den Werten aus x und y.

  • Point(Point p)

    Legt einen neuen Punkt an und initialisiert ihn mit den gleichen Koordinaten, die der übergebene Punkt hat. Wir nennen so einen Konstruktor auch Copy-Konstruktor.

Ein Konstruktor ohne Argumente ist der parameterlose Konstruktor, selten auch No-Arg-Konstruktor genannt. Jede Klasse kann höchstens einen parameterlosen Konstruktor besitzen, es kann aber auch sein, dass eine Klasse keinen parameterlosen Konstruktor deklariert, sondern nur Konstruktoren mit Parametern, also parametrisierte Konstruktoren.

[zB]  Beispiel

Die drei folgenden Varianten legen ein Point-Objekt mit denselben Koordinaten (1, 2) an; java.awt.Point ist mit Point abgekürzt:

Point p = new Point(); p.setLocation( 1, 2 );

Point q = new Point( 1, 2 );

Point r = new Point( q );

Als Erstes steht der parameterlose Konstruktor, im zweiten und dritten Fall handelt es sich um parametrisierte Konstruktoren.

 


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