III Klassen und Vererbung 15 Konstruktoren, Attribute und Methoden 15.1 Die Klasse Punkt Version 1 |
|
Klasse und Objekte | Wenn wir
von einem Punkt P in einer Ebene sprechen, sprechen wir von einer Klasse.
Wenn wir vom P1(2|3) sprechen, meinen wir eine Instanz von P
also ein Objekt. (vgl. dazu
3.1 Klasse und Objekt) Wir modellieren die Klasse in Java: Objekte dieser Klasse sollen erzeugt, die Punkte verschoben und am Ursprung gespiegelt werden können. Standardmäßig wird beim Erzeugen eines nicht weiter spezifizierten Punktes der Punkt (0|0) erzeugt werden. Man soll aber auch jeden beliebigen Punkt P(x0|y0) der Zahlenebene gezielt erzeugen können. Mit den Punkten wollen wir aber auch operieren können, d.h. sie z.B. in dem Koordinatensystem verschieben oder am Ursprung spiegeln können. Um eine optische Darstellung der Punkte scheren wir uns nicht. In UML hat die Klasse dann die Darstellung:
|
Implementierung der
Klasse
Download: |
class Punkt { public int x,y; public Punkt() { x=0; y=0; } public Punkt(int xNeu, int yNeu) { x = xNeu; y = yNeu; } public void verschiebe(int dx, int dy) { x += dx; y += dy; } public void spiegleAmUrsprung() { x = -x; y = -y; } } |
Attribute |
Die Attribute der Klasse sind
x
und y,
gemeint sind damit die x- und y-Koordinate eines Punktes. Diese Attribute
haben für jedes Objekt, das wir nach dem Bauplan dieser Klasse anlegen
konkrete, individuelle Werte. |
Konstruktoren |
Die Konstruktoren einer Klasse dienen dazu, Objekte
von ihr zu erzeugen. Wir
erkennen sie daran, dass sie wie Methoden aufgebaut sind, aber keinen
Rückgabewert, nicht einmal
void,
besitzen. Weiter haben die Konstruktoren den gleichen Namen wie ihre
Klasse. Wenn man eine Klasse schreibt, und keinen Konstruktor implementiert, so besitzt sie automatisch den sog. Standardkonstruktor. In unserem Fall wäre dies Punkt(){}; Der Kompiler würde ihn automatisch hinzufügen. Da zwischen den geschweiften Klammern kein weiterer Text steht, kann man mit ihm zwar Objekte anlegen, diese haben aber noch keine Eigenschaften.1) Im Falle unseres Punktes macht das wenig Sinn. Wenn wir wollen, dass die Koordinaten des Punktes, der mit dem Standardkonstruktor erzeugt wird, immer 0 sind, der Standardkonstruktor also immer den Punkt P(0|0) erzeugt, so überschreiben wir den implizit vorhanden Konstruktor durch: public Punkt() { Große Flexibilität erreichen wir dadurch, dass Java erlaubt für eine Klasse mehrere Konstruktoren zu implementieren. Es kann Sinn machen, z.B. auch einen Punkte zu erzeugen, deren Koordinaten vor dem Erzeugen berechnet wurden. In diesem Fall wäre folgender Konstruktor sinnvoll: public Punkt(int xNeu,
int yNeu) { Natürlich tragen beide Konstruktoren
den
gleichen Bezeichner. Damit ein Kompiler die beiden Konstruktoren unterscheiden
kann, müssen sie sich in der Signatur unterscheiden., die Parameterliste
müssen also unterschiedlich viele Parameter haben oder, wenn die Anzahl
der Parameter bei beiden gleich ist, müssen sie sich mindestens im Typ
einer Variablen in der Poarameterliste unterscheiden. |
Methoden |
Über die Implementierung der Methoden in der Klasse
Punkt
brauchen wir nicht mehr viel Worte verlieren. Wie das geht, haben wir
schon in der Klasse Mathematik gesehen. Allerdings liefern die Methoden
keinen Wert an den Aufrufer zurück, weshalb sie als Rückgabewert
void erhalten. Und
ein weiterer wesentlicher Unterschied, sie sind nicht statisch, d.h. sie
sind nicht an die Klasse sondern an ein Objekt 'gebunden'. Wir werden
diesen Unterschied gleich beim Aufruf der Methoden erkennen. Um unsere Klasse Punkt in ihrer Funktionalität zu testen, implementieren wir ein kleines Testprogramm. Der Quellkode ist selbsterklärend. |
Download: PunktDemo.java |
Ein Demo-
oder Testprogramm dient zum überprüfen der Konstruktoren und Methoden
einer Fachklasse. Sie schreibt man in der Regel als kleine
Applikationsprogramme ohne grafische Oberfläche. Das letztere bleibt der
sog. GUI-Klasse (Grafical User Interface)
vorbehalten, mit denen wir uns in Kap 19 beschäftigen werden. Der
Quelltext zum Demoprogramm:import info1.*; public class PunktDemo{ public static void main(String[] args){ int x,y; System.out.print("x-Wert: "); x = Console.in.readInt(); System.out.print("y-Wert: "); y = Console.in.readInt(); Punkt p1 = new Punkt(); Punkt p2 = new Punkt(x,y); System.out.println("P1(" + p1.x +"/" + p1.y +")"); System.out.println("P2(" + p2.x +"/" + p2.y +")"); p1.verschiebe(2,5); p2.spiegleAmUrsprung(); System.out.println("P1 ist um 2 in x- und 5 in y-Richtung verschoben"); System.out.println("P1(" + p1.x +"/" + p1.y +")"); System.out.println("P2 ist am Ursprung gespiegelt"); System.out.println("P2(" + p2.x +"/" + p2.y +")"); } } x-Wert: 4 y-Wert: 4 P1(0/0) P2(4/4) P1 ist um 2 in x- und 5 in y-Richtung verschoben P1(2/5) P2 ist am Ursprung gespiegelt P2(-4/-4) |
Ausgabe |
Nachdem x- und y-Wert eines Punktes
eingelesen sind, wird ein Punkt mit dem Standardwerten (0/0) und ein
weiterer mit den eingegeben Werten, also (4/4) erzeugt und als p1 und p2
angezeigt. p1 wird verschoben und p2 am Ursprung gespiegelt. Danach werden
die Punkte noch einmal ausgegeben. |
Bemerkungen zum Quellkode |
Wir erkennen, wie man Instanzen der
Klasse Punkt deklariert und sie dann auch erzeugt: Zunächst nennt man den
Namen der Klasse von der man ein Objekt anlegen möchte. Es folgt der
Name, den die Instanz tragen soll, also
p1
bzw. p2.
Folgten jetzt Semikola, so wären die Objekte deklariert aber noch nicht
instanziiert, Objekte selbst sind somit noch nicht angelegt. Die geschieht
unter Verwendung des
new-Operators.
Dieser benutzt den Konstruktor, um die eigentliche Erzeugung, auch
Instanziierung genannt, vorzunehmen. In unserem Beispiel kommen beide
Konstruktoren zum Einsatz. Wie man auf die Koordinaten der Objekte zugreift, erkennt man in den Ausgaben. So liefert p1.x die x-Koordinate des Objektes p1 und p2.y die y-Koordinate des Objektes p2. Es handelt sich in beiden Fällen um einen direkten, lesenden Zugriff auf die Attribute der Objekte p1 und p2. Ein entsprechend direkter schreibende Zugriff sieht so aus: p1.y = 4; Damit hat man den y-Wert des
Objektes p1 direkt geändert. Diese direkte Zugriffe auf Attribute eines
Objektes versucht man in aller Regel zu vermeiden, ja zu verhindern.
Direkte Zugriffe auf Objektattribute widersprechen nämlich dem Prinzip des
'Information hiding's. |
Fußnoten | |
Tatsächlich hat die mit dem 'leeren' Standardkonstruktor erzeugte Klasse
schon Eingenschaften. Denn jede Klasse erbt von der Klasse Object und
damit von ihr z.B. die Methoden
clone() oder
toString().
Wir werden im Laufe des Kurses mehr davon erfahren.
[zurück] |
|
zu | 15.2 Kapselung |
zur Startseite | www.pohlig.de (C) MPohlig 2005 |