7. Klassen und Objekte (Teil 1)class, newJetzt wollen wir uns der OOP-Konzeption nähern. Der zentrale
Begriff ist der einer Klasse
(class).
Bisher haben wir nur Appliktionsklassen erstellt (die man an der
main()-Methode erkennt und die hierdurch ausführbar werden). Von
diesen will man nie "Instanzen" (Objekte) schaffen, sie sind Beispiele
statischer Klassen, deren sämtliche Methoden und Variable den
Zusatz Die Klassen, die wir jetzt besprechen wollen, sind neue Datentypen, die die ProgramiererIn selbst schafft, oder die ein von "Profis" zur Verfügung gestelltes package anbietet. Variable vom Typ einer Klasse heißen Objekte, sie erhalten durch ihre Deklaration einen Bezeichner. Zu einer solchen (nicht statischen) Klasse gehört immer ein Konstruktor, der ihre Objekte initialisiert. Eine Klasse hat gewisse Daten (auch Attribute oder Variable der Klasse genannt) und verfügt über Methoden. Wenn die Klasse nicht den Zusatz static besitzt, also keine statische Klasse ist, kann man eine Instanz (ein Objekt) dieser Klasse mit Hilfe des new-Operators und des Konstruktors initialisieren (allokieren). Danach kann auf die Daten über die definierten Methoden des Objektes mit Hilfe der Punktnotation zugegriffen werden. Wir kennen dies im Prinzip schon für die klassenverwandten
Datentypen Zeichenkette (String) und Feld: So wird ein
7.1 Die Klasse "KomplexeZahl"Auf den mathematischen Hintergrund komplexer Zahlen werde ich in der Vorlesung eingehen. Festhalten will ich hier nur, dass eine komplexe Zahl durch zwei reelle Zahlen, nämlich ihren Real- und ihren Imaginärteil charakterisiert ist. Komplexe Zahlen kann man multiplizieren, addieren, man kann durch von Null verschiedene komplexe Zahlen dividieren: sie gehorchen denselben Rechenregeln wie die reellen Zahlen, sie bilden einen Körper. Die Daten (Attribute, Variable) von Objekten einer Klasse, die komplexe Zahlen
darstellt, werden
also sinnvollerweise Real- (Re) und Imaginärteil
(Im) sein (wie verwenden gegen die
Konvention große Anfangsbuchstaben). In der darauf folgenden
Applikationsklasse Wir wollen die Klasse noch mit einer Methode versehen, die feststellt,
ob die komplexe Zahl reell, d.h., ob ihr Imaginärteil null
ist (da man wegen Rundungsfehler class KomplexeZahl1{ //Daten: double Re, Im;//gegen Konvention mit grossen Anfangsbuchstaben //Konstruktor: KomplexeZahl1(double x, double y){ Re=x; Im=y; }//Ende Konstruktor boolean reell(){ boolean w=false; if (Math.abs(Im)<1E-12) w=true; return w; }//Ende reell() }//Ende class KomplexeZahl1 Diese Klasse kann zwar kompiliert, aber nicht ausgeführt werden,
da es sich nicht um eine Applikationsklasse handelt (sie enthält
keine class Komplex1{ public static void main(String[] args){ KomplexeZahl1 z = new KomplexeZahl1(1.1, 2.3); boolean w=z.reell();//false }//Ende main()( }//Ende class Komplex1 Die wichtigste Zeile ist die, in der der Konstruktor in Verbindung mit
dem new-Operator eingesetzt wird, um
ein Objekt namens Die imaginäre Einheit i hätte man mit
Jetzt geben wir eine Applikationsklasse an, die eine Methode vorsieht, die komplexe Zahlen miteinander multipliziert und eine solche Multiplikation auch für konkrete Zahlen ausführt: class Komplex2{ static KomplexeZahl1 mal(KomplexeZahl1 z1, KomplexeZahl1 z2){ double w1, w2; w1=z1.Re*z2.Re-z1.Im*z2.Im; w2=z1.Re*z2.Im+z1.Im*z2.Re; return new KomplexeZahl1(w1,w2); }//Ende mal() public static void main(String[] args){ KomplexeZahl1 z1 = new KomplexeZahl1(1.1, 2.3); KomplexeZahl1 z2 = new KomplexeZahl1(1.1, -2.3); KomplexeZahl1 w=mal(z1,z2); if (w.reell()) System.out.println("z1*z2 ist reell"); }//Ende main()( }//Ende class Komplex2 Beachten Sie, dass sowohl die beiden Parameter als auch der
Rückgabewert der Methode 7.2 KonstruktorenBezeichner, Parameter, thisDer Konstruktor einer Klasse muss
stets den gleichen Namen wie die Klasse haben. Ein Klassenblock
muss zwar keinen Konstruktor enthalten (dann gibt es den
Default-Konstruktor ohne Parameter), diesen Fall wollen wir aber in
diesem Kurs ausschließen, wenn wir von statischen Klassen (wie
z.B. die Applikationsklassen), für die Konstruktoren keinen Sinn
machen, da nie eine Instanz dieser Klasse gebildet werden soll,
absehen. Konstruktoren sind Methoden verwandt: sie haben i.a.
Parameter, jedoch keinen Rückgabewert, ohne dass dies jedoch mit
dem Zusatz Zuweilen möchte man den Parametern eines Konstruktors den gleichen Namen geben wie sie die Daten der Klasse haben. Dies geht unter Verwendung des Schlüsselworts this: class KomplexeZahl2{ //Daten: double Re, Im; //Konstruktor: KomplexeZahl2(double Re, double Im){ this.Re=Re; this.Im=Im; }//Ende Konstruktor boolean reell(){ return (Math.abs(Im)<1E-12); }//Ende reell() }//Ende class KomplexeZahl2 Die Verwendung von this bedarf einer Erklärung: Wenn die Bezeichner von Parametern von Konstruktoren mit denen von Daten der Klasse identisch sind, haben die Parameter als lokale Parameter Vorrang. Um auf die Daten zugreifen zu können, muss man this in der Punktnotation voranstellen, welches stellvertretend für den Bezeichner eines später zu konstruierenden Objektes steht. 7.3 Zugriffsrechte (Sichtbarkeit) Teil 1public, privateKlassen, Daten, Methoden und Konstruktoren enthalten in der Regel einen vorgestellten Zusatz (Modifizierer oder (engl.) Modifier genannt), der die Zugriffsrechte bestimmt, die eine Rolle spielen, wenn in anderen Klassen, z.B. in Applikationsklassen, Objekte der betreffenden Klasse instanziert werden und auf Daten und Methoden des Objekts zugegriffen werden soll. Will man z.B. ausschließen, dass ein Objekt namens
Allerdings ruft dann die Zeile
//KomplexeZahl3 ... private double Re, Im; ... //Methoden: ... public double getRe(){ return Re; } ... }//Ende class Jetzt erreicht die folgende Applikationsklasse das gleiche Ziel wie
die Klasse class Komplex3{ public static void main(String[] args){ KomplexeZahl3 z = new KomplexeZahl3(1.1, 2.3); System.out.println("Re z="+z.getRe()+" Im z=" +z.getIm()); }//Ende main() }//Ende class Komplex3 Auf jeden Fall sollte die Klasse Ein wesentlicher Vorteil bei einer Einschränkung von Zugriffsrechten bzw. der Sichtbarkeit ist, dass der Benutzer sich nur die öffentlichen Daten, Klassen und Methoden merken muss. Will man z.B. von den ungeheuer mächtigen Grafikklassen von Java Gebrauch machen, muss man in jedem Detail die Bezeichner der öffentlichen Klassen, ihrer öffentlichen Daten und Methoden, aber auch den Typ dieser Daten und die Paramterliste dieser Methoden kennen, im Zweifelsfall nachschlagen oder auswendig lernen. Die intern vom Programmierer verwendeten nicht öffentlichen Klassen, Daten und Methoden interessieren nicht! Neben private, public ist noch der Zusatz protected wichtig. Er tritt aber nur in Verbindung mit Unterklassen auf und erlaubt die Sichtbarkeit innerhalb aller Unterklassen. 7.4 Die Klasse "Winkel", Polarkoordinaten einer komplexen Zahl und ein zweiter Konstruktor der Klasse "KomplexeZahl"Komplexe Zahlen sind nicht nur durch ihre Real- und
Imaginärteile, sondern auch durch ihre Polarkoordinaten
(Betrag und Winkel) bestimmt. Die Winkel werden im Bogenmaß
gemessen und können auf das Intervall [0, 2*PI) beschränkt
werden. Ich führe jetzt eine etwas künstlich anmutende
Klasse class Winkel{ private double phi; Winkel(double a){ while (a>= 2*Math.PI) a-=2*Math.PI; while (a<0) a+=2*Math.PI; phi=a; }//Ende Konstruktor Winkel() public double getphi(){ return phi; } }//Ende class Winkel Jetzt können wir einen zweiten Konstruktor in der Klasse
class KomplexeZahl4{ private double Re, Im; //Konstruktor 1 KomplexeZahl4(double x, double y){ Re=x; Im=y; } //Konstruktor 2 KomplexeZahl4(double r, Winkel W){ double phi=W.getphi(); Re=r*Math.cos(phi); Im=r*Math.sin(phi); } public double getRe(){ ... } }//Ende class KomplexeZahl4 Beachten Sie, dass beide Konstruktoren den gleichen Namen haben, dass
sich ihre Parametertypen aber unterscheiden. Hätte ich nicht die
Klasse
7.5 Die Klasse MathWir haben ganz pragmatisch mathematische Funktionen (Wurzel, Potenz, sin, cos) sowie die Kreiszahl PI durch Voranstellen von Math mit einem anschließenden Punkt verwendet. Dabei sind sqrt(), pow(), sin(), cos() Methoden der von Java zur Verfügung gestellten (statischen) Klasse Math, während PI eine Konstante dieser Klasse ist. Weitere Methoden der Klasse Math sind abs() (Betragsfunktion), tan(), atan() (arcustangens), min(), max() (Minimum, Maximum von zwei Zahlen), exp() (Exponentialfunktion), log() (natürlicher Logarithmus) und wenige mehr. Weitere Informationen findet man in der zugehörigen Klassenbeschreibung unter http://www.math.uni-hamburg.de/doc/java/jdk/docs/api/java/lang/Math.html . Weiter mit 8. Klassen und Objekte (Teil 2).
|
![]() ![]() |
Impressum | 2009-03-31, wwwmath (WL) |