Letzte Woche Universität Paderborn Prof. Dr. Heike Wehrheim Klassendefinitionen Konstruktoren Objektmethoden Objektvariablen Objekterzeugung Sichtbarkeiten: private, public Klassennamen als Typen Objektreferenzen, null Überladen von Methoden GPI, WS 07/08 413 Benennung von Variablen Universität Paderborn Prof. Dr. Heike Wehrheim Namen von lokalen Variablen und von Objektvariablen kollidieren nicht: gleiche Namen für Objektvariablen und lokale Variablen/Parameter sind möglich Das bringt ein Problem mit sich: lokale Variablen können Objektvariablen „verdecken“ Beispiel: class Circle { Gibt immer 25 aus, unabhängig vom Wert der int x; Objektvariable x : die lokale … Variable x verdeckt die void bla () { Objektvariable x int x = 25; System.out.println(x); } } GPI, WS 07/08 414 Universität Paderborn Prof. Dr. Heike Wehrheim this Innerhalb einer Methode bezieht sich die spezielle Objektreferenz this immer auf das Objekt, für das die Methode momentan aufgerufen wurde. Benutzung z.B.: eine Variable des Objekts ansprechen, die durch lokalen Namen verdeckt ist this.meineVariable die eigene Referenz einer anderen Methode übergeben anderesObjekt.dessenMethode(this) GPI, WS 07/08 415 Beispiel in Circle Universität Paderborn Prof. Dr. Heike Wehrheim class Circle { int x; … void bla () { int x = 25; System.out.println(this.x); } } Gibt nun den Wert der Objektvariable x aus GPI, WS 07/08 416 Beispiel in Klasse Student Universität Paderborn Prof. Dr. Heike Wehrheim Alternative Formulierung des neuen Konstruktors StudentEinfach(int mNum, int wieAlt, char studiengang) { matNr = mNum; alter = wieAlt; this.studiengang = studiengang; } Die Variable studiengang des Objektes wird verdeckt von dem formalen Parameter studiengang. Mit this.studiengang kann die Objektvariable explizit angesprochen werden. GPI, WS 07/08 417 this und Konstruktoren Universität Paderborn Prof. Dr. Heike Wehrheim Die Objektreferenz this kann auch zum Aufruf eines Konstruktors aus einem anderen heraus benutzt werden. Dieser Aufruf muss dann die erste Anweisung im Konstruktor sein. Beispiel: StudentEinfach(int mNum, int wieAlt, char studiengang) { this(mNum, wieAlt); Aufruf des Konstruktors StudentEinfach(int, int) this.studiengang = studiengang; } GPI, WS 07/08 418 Objekte vergleichen Universität Paderborn Prof. Dr. Heike Wehrheim Wenn Objekte bezüglich der Werte ihrer Variablen verglichen werden sollen, kann nicht == verwendet werden: Der Vergleich obj1 == obj2 liefert nur true, wenn die Objektreferenzen gleich sind. Stattdessen eine Methode istGleich für die Klasse schreiben, public boolean istGleich (Klassenname obj), die den Vergleich macht (eigentlich equals, aber das kommt später). Damit kann ein Objekt obj1 mit einem Objekt obj2 verglichen werden: obj1.istGleich(obj2) GPI, WS 07/08 419 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim class Zahl { public int zahl; void incr() { zahl++; } void decr() { zahl--; } public boolean istGleich(Zahl zahlObjekt) { return this.zahl == zahlObjekt.zahl; } Zahl(int wert) { zahl = wert; } } Objektvergleiche.java GPI, WS 07/08 420 Test Universität Paderborn Prof. Dr. Heike Wehrheim public class Objektvergleiche { public static void main (String [] args) { Zahl z1, z2, z3; }} z1 = new Zahl(9); z2 = new Zahl(11); z3 = z1; z2.decr(); z3.incr(); System.out.println(z1 == z2); System.out.println(z1.istGleich(z2)); System.out.println(z2.istGleich(z1)); System.out.println(z1 == z3); System.out.println(z1.istGleich(z3)); Was liefert false, was true? GPI, WS 07/08 421 Vergleichen von Objekten Universität Paderborn Prof. Dr. Heike Wehrheim obj1 == obj2 vergleicht die Referenzen, nicht die Inhalte Eigene Methode istGleich schreiben, die Inhalte vergleicht Ähnlich: Kopieren von Objekten obj1 = obj2; erzeugt keine Kopie, sondern obj1 und obj2 haben nachher Referenz auf das gleiche Objekt GPI, WS 07/08 422 Objekte kopieren Universität Paderborn Prof. Dr. Heike Wehrheim Kopie eines Objektes erzeugen (d.h. neues Objekt mit gleichen Werten der Objektvariablen) Beispiel: ein Kopierkonstruktor für Circle Circle(Circle c) { x = c.getX(); y = c.getY(); radius = c.getRadius(); } GPI, WS 07/08 423 Aufpassen bei Referenztypen Universität Paderborn Prof. Dr. Heike Wehrheim Circle2 hat Punkt-Objekt als Mittelpunkt Kopieren von Circle2 Circle2(Circle2 c) { mittelpunkt = c.getMittelpunkt(); radius = c.getRadius(); } erzeugt eine „flache Kopie“: das Punkt-Objekt wird nicht kopiert Liefert Punkt-Objekt Circle2(Circle2 c) { Punkt p = new Punkt(0,0); p.setX(c.getMittelpunkt().getX()); p.setY(c.getMittelpunkt().getY()); mittelpunkt = p; Annahme: es gibt radius = c.getRadius(); diese setter und } getter erzeugt eine „tiefe Kopie“ GPI, WS 07/08 424 Nochmal vergleichen Universität Paderborn Prof. Dr. Heike Wehrheim Genauso gibt es „flaches“ und „tiefes“ Vergleichen: boolean istGleich(Circle2 c) { // flach return (this.getRadius() == c.getRadius() && this.getMittelpunkt() == c.getMittelpunkt() ); } versus boolean istGleich(Circle2 c) { // tief return (this.getRadius() == c.getRadius() && this.getMittelpunkt().istGleich( c.getMittelpunkt()) ); } Methode Vergleich der Punkte wird delegiert an Punkt-Objekt GPI, WS 07/08 istGleich von Klasse Punkt 425 Klassenvariablen/methoden Universität Paderborn Prof. Dr. Heike Wehrheim bisher: Variablen und Methoden beschreiben Daten und Operationen der Objekte Objektvariablen, Objektmethoden nun: Variablen und Methoden der Klasse Klassenvariablen, Klassenmethoden (das sind die static Variablen und Methoden, die wir bereits kennen) auch: statische Datenelemente GPI, WS 07/08 426 Klassenvariablen/methoden Universität Paderborn Prof. Dr. Heike Wehrheim Klassenvariable und Klassenmethoden gehören inhaltlich zur Klasse insgesamt. Sie beziehen sich also nicht (!) auf ein spezielles Objekt. Auf sie wird über den Klassennamen zugegriffen. Klassenvariablen und -methoden werden bei der Deklaration durch static gekennzeichnet. Eine Klassenvariable existiert nur einmal pro Klasse - nicht für jedes Objekt. GPI, WS 07/08 427 Universität Paderborn Prof. Dr. Heike Wehrheim Beispiel 1.sqrt ist eine Klassenmethode der Klasse Math, daher Zugriff mit Math.sqrt(); 2. Beispiel in der Klasse Student: Speichern der Anzahl der Studenten in einer Klassenvariable anzahlStud neuer Konstruktor Klassenvariablen dürfen in Klassen- und in Objektmethoden verändert werden! GPI, WS 07/08 class Student { private static int anzahlStud = 0; ... Student(int wieAlt) { anzahlStud++; matNummer = anzahlStud; alter = wieAlt; ... } } 428 Klassenmethoden Universität Paderborn Prof. Dr. Heike Wehrheim Klassenmethoden und –variablen definieren Funktionalität, die unabhängig von Objekteigenschaften für alle Objekte der Klasse nützlich ist. Sie gehören der ganzen Klasse. Eine Klassenmethode kann nicht auf Objektvariable zugreifen! Klassenmethoden können andere Klassenmethoden aufrufen. Objektmethoden können Klassenmethoden aufrufen. GPI, WS 07/08 429 Universität Paderborn Prof. Dr. Heike Wehrheim Beispiel Klasse Student Beispiel in der Klasse Student: Rückgabe der Anzahl der Studenten in einer Klassenmethode class Student { ... private static int anzahlStud = 0; static int getAnzahlStud() { return anzahlStud; } ... } Klasse IAmt kann z.B. Student.getAnzahlStud() aufrufen Klassenname!! GPI, WS 07/08 430 Weiteres Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Klasse der Funktion GGT - Klassenmethoden ggT und main class GGT_Funktion { static int ggT (int a, int b) { while (a != b) { if (a > b) a = a - b; else b = b - a; } return a; } static public void main (String[] args) { int g; g = ggT(90,54); System.out.print("GGT von 90 und 54: " + g); }} Hier kein Klassenname nötig: gleiche Klasse GPI, WS 07/08 431 main Universität Paderborn Prof. Dr. Heike Wehrheim Eine bekannte statische Methode: public static void main (String [] args) { … } main muss statisch sein, weil beim Start des Programms noch keine Objekte existieren. Aus main heraus können andere statische Methoden aufgerufen werden (solange sie aus derselben Klasse kommen auch ohne den Klassennamen voranzustellen). Erst wenn ein erstes Objekt erzeugt Das haben wir die wurde, können dafür Objektmethoden ersten 6 Wochen so gemacht aufgerufen werden. GPI, WS 07/08 432 Universität Paderborn Prof. Dr. Heike Wehrheim Klassen- vs. Objektmethoden Wollen Klasse Circle2 um eine Methode erweitern, die den Abstand zweier Kreise voneinander (gesehen vom Mittelpunkt aus) berechnet. Kann als Klassen- oder Objektmethode implementiert werden. Ein Unterschied: eine Objektmethode kennt bereits ein Objekt (nämlich das, von dem die Methode gerade aufgerufen wird) eine Klassenmethode kennt kein Objekt GPI, WS 07/08 433 In Java Universität Paderborn Prof. Dr. Heike Wehrheim public class Circle3 { private Punkt mittelpunkt; private double radius; Circle3 (Punkt punkt, double ir) { mittelpunkt = punkt; radius = ir; } // Klassenmethode distance static double distance (Circle3 c1, Circle3 c2) { double distx, disty; distx = Math.abs (c1.getX() - c2.getX()); disty = Math.abs (c1.getY() - c2.getY()); return (Math.sqrt (distx * distx + disty * disty)); } // Objektmethode distance double distance (Circle3 c1) { double distx, disty; distx = Math.abs (c1.getX() - this.getX()); disty = Math.abs (c1.getY() - this.getY()); return (Math.sqrt (distx * distx + disty * disty)); }} GPI, WS 07/08 434 Ausprobieren Universität Paderborn Prof. Dr. Heike Wehrheim public class Circle3Prog { public static void main (String [] args) { Circle3 kreis1, kreis2; Punkt punkt1 = new Punkt(10,4); Punkt punkt2 = new Punkt(8,3); double dist; kreis1 = new Circle3(punkt1,15); kreis2 = new Circle3(punkt2,100); Aufruf der Objektmethode dist = kreis1.distance(kreis2); System.out.println("Abstand 1 und 2: " + dist); dist = Circle3.distance(kreis1,kreis2); System.out.println("Abstand 1 und 2: " + dist); }} Aufruf der Klassenmethode GPI, WS 07/08 435 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Was sind Klassenmethoden/variablen, was Objektmethoden/variablen? Klasse MP3PlayerX1 Variablen: Methoden farbe - batterieLaden verkaufspreis - abspielen verkaufteExemplare - laut/leise lautstärke - rückruf aufgespielteStücke - musikstückWählen - getVerkaufteExemplare GPI, WS 07/08 436 … fortgesetzt Universität Paderborn Prof. Dr. Heike Wehrheim Klasse (K), Objekt (O) Variablen: farbe O verkaufspreis K (O) verkaufteExemplare K lautstärke O aufgespielteStücke O GPI, WS 07/08 Methoden - batterieLaden O - abspielen O - laut/leise O - rückruf K - musikstückWählen O - getVerkaufteExemplare K 437 Statische Methoden Universität Paderborn Prof. Dr. Heike Wehrheim … können nur auf statische Datenelemente direkt zugreifen, … können nur andere statische Methoden direkt aufrufen, … können this nicht benutzen, weil es kein Zielobjekt gibt. GPI, WS 07/08 438 Entwurf einer Klasse Universität Paderborn Prof. Dr. Heike Wehrheim Entwurf einer Klasse Stempel, die Tickets einer bestimmten Größe, aber mit unterschiedlichen Inhalten druckt (siehe VL Funktionen/Prozeduren) ======= =55555= =55555= ======= Erster Schritt: Welche Variablen werden gebraucht? die Größe beschreiben: hoehe, breite Form der Ränder festlegen: rand Wieso Klassenvariable? In Java: private int hoehe, breite; private static final char rand = ´=´; GPI, WS 07/08 439 Konstruktor Universität Paderborn Prof. Dr. Heike Wehrheim Zweiter Schritt: Wie sieht der Konstruktor aus? er soll festlegen, wie die Größe der Tickets dieses Objekts sein soll Stempel(int h, int b) { hoehe = h; breite = b; } GPI, WS 07/08 440 Methoden Universität Paderborn Prof. Dr. Heike Wehrheim Dritter Schritt: Was sind die Methoden? Anlehnung an die Funktionen des TicketDruckers: eine Methode für eine Reihe, eine Methode für das ganze Ticket private void eineZeile (char c) { System.out.print (rand); Warum private? int i = 2; while (i < breite) { System.out.print (c); i = i+1; } System.out.println (rand);} public void einTicket (char c) { eineZeile ('='); int i = 2; while (i < hoehe) { eineZeile (c); i = i+1; } eineZeile ('=');} Stempel.java GPI, WS 07/08 441 Universität Paderborn Prof. Dr. Heike Wehrheim Ausprobieren Vierter Schritt: Klasse testen Ein paar Objekte erzeugen und Tickets ausgeben public class StempelProg { public static void main (String [] args) { Stempel stempel1 = new Stempel(5,4); Stempel stempel2 = new Stempel(10,3); stempel1.einTicket('?'); stempel2.einTicket('4'); } StempelProg.java } GPI, WS 07/08 442 Eigene Aufgabe Universität Paderborn Prof. Dr. Heike Wehrheim Überlegen Sie sich die Variablen und Methoden einer Klasse Hotel! Gibt es andere Klassen, die dafür entworfen werden könnten? (Nicht Implementierung in Java) GPI, WS 07/08 443 Ideen zu Hotel Universität Paderborn Prof. Dr. Heike Wehrheim Klasse Hotel benutzt Klasse Gast und Klasse Angestellter Gast hat Name, Adresse, Kreditkartennummer, … kann Name/Adresse ändern, Auskunft über Kreditkartennummer geben, … Angestellter hat Name, Adresse, Gehalt, … kann Gehaltsstufe raufsteigen, Name/Adresse ändern, sich krank melden, … Hotel hat Räume, Bettenanzahl, Gäste, Reservierungen, Personal, … kann neue Reservierungen annehmen, Gäste aufnehmen/bezahlen lassen, neuen Manager einstellen, … GPI, WS 07/08 444 Begriffe GPI, WS 07/08 Universität Paderborn Prof. Dr. Heike Wehrheim 445 Fragen Universität Paderborn Prof. Dr. Heike Wehrheim 1. Wenn wir mit einer Methode zwei ganze Zahlen zurückgeben müssen, können wir verwenden a) zwei int-Parameter b) ein Objekt als Rückgabewert c) zwei Rückgabewerte d) Antwort a) oder b) GPI, WS 07/08 446 Fragen II Universität Paderborn Prof. Dr. Heike Wehrheim 2. Erlaubt oder nicht? class A { int x; A() { x = 0; } A(int y) { x = y; } A(int x) { this.x = x; } } 3. Erlaubt oder nicht? class A { int x; A() { x=0; A(8); } A(int y) {x = y; } } GPI, WS 07/08 447 Fragen III Universität Paderborn Prof. Dr. Heike Wehrheim 4. Eine Klassenmethode kann auf a) Klassenvariablen b) ihre Parameter c) Objektvariablen d) a) und b) zugreifen. 5. Mit dem Schlüsselwort static kennzeichnet man a) Objektvariablen oder –methoden b) Klassenvariablen oder –methoden c) Konstanten GPI, WS 07/08 448 Fragen IV Universität Paderborn Prof. Dr. Heike Wehrheim 6. Gegeben folgende Deklarationen class A { private B meinB; A(B b) { meinB = b; } } class B{ private A meinA; B() { meinA = null; } } Erlaubt oder nicht? a) A objA = new A(new B()); b) B objB = new B(new A(null)); GPI, WS 07/08 449