Java FH Merseburg SS 2002 2.3 Klassenprogrammierung 2.3.1 Beispielprogramm Das Programm beinhaltet eine Verwaltung von Planeten. Dazu werden zunächst verschiedene Klassen angelegt. public class { public public public Planet // Klasse als Datenspeicher struct long id; String name; Planet orbit; // Umlaufbahn um welchen Planeten public static long naechsteID = 0; // fortlaufende Numerierung } import java.io.*; public class Utilities { public static void waitForReturn () { BufferedReader din = new BufferedReader(new InputStreamReader(System.in)); try { System.out.println("\nBitte Return-Taste druecken..."); din.readLine(); } catch (IOException e) { System.err.println("Fehler: "+e); } } } Hauptprogramm – Steuerprogramm public class Control { public static void main(String[] args) { Planet sonne, erde; Utilities wait; sonne = new Planet(); sonne.id = Planet.naechsteID++; sonne.name = "Sonne"; sonne.orbit = null; // kein import // Referenzen // Referenz // Instanzierung // Sonne ist das Zentrum erde = new Planet(); erde.id = Planet.naechsteID++; erde.name = "Erde"; erde.orbit = Sonne; wait = new Uti(); wait.waitForReturn(); } } 841119650 -1- Java FH Merseburg SS 2002 Operationen auf Objekte erfolgen in Java durch die Angabe von Objektreferenz.Methoden- oder Variablenname: Referenz.variablenname; Referenz.methodenname(parameter); Klassenbeziehungen: Planet Instanzen haben eigenen Zustand sonne erde Veränderungen hier haben keine Auswirkungen auf Sonne Problem: Die ID der Planeten ist eine Eigenschaft die zentral verwaltet werden muß, und nicht in der Instanz bearbeitet werden kann. Sie wird daher als Instanzvariable bzw. Klassenvariable über den Modifier static deklariert. 2.3.2 Zugriffskontrolle / Modifiers Die Attribute und Methoden sind immer für den Code derselben Klasse verfügbar, public: überall dort verwendbar, wo auch Klasse verwendbar ist private: nur in der Klasse selbst verwendbar Datenkapselung ! protected: verwendbar für Unterklassen und im Packet static: Klassenvariablen alle Instanzen besitzen eine gemeinsame Kopie dieser Variablen ohne Modifier: wie protected Beispiel: Static long naechstes, 2.3.3 Konstruktoren Konstruktoren setzen einen Anfangswert für die Attribute des neu erzeugten Objektes (Initialisierung). Oft ist auch mehr notwendig z. B. Berechnungen durchführen. Konstruktoren sind spezielle methodenähnliche Anweisungsfolgen, die denselben Namen haben wie die Klasse, keine oder mehrere Parameter haben und keinen Rückgabewert. new: - Instanzvariablen erhalten voreingestellte Anfangswerte - Zuweisung der Initialisierungsausdrücke - Aufruf der Konstruktoren 841119650 -2- Java FH Merseburg SS 2002 public class Planet { public long id; public String name; public Planet orbit; private static long naechsteID = 0; // nur Klasse Planet hat // Zugriff Planet() {id = naechsteID++ } // Konstruktor } Durch die Verlagerung der ID Nummernvergabe in die Klasse Planet können Fehler vermieden werden. Folglich fehlt im neuen Hauptprogramm die Zeile xxx.id = Planet.naechsteID++. public class Control { public static void main(String[] args) { Planet sonne, erde; Utilities wait; // sonne = new Planet(); sonne.name="Sonne"; sonne.orbit=null; erde = new Planet(); erde.name="Erde"; erde.orbit=Sonne; ... // id = 0 ist nicht mehr erforderlich // id = 1 // waitForReturn } } Der Planet-Konstruktor ist nun die einzige Einheit, die die ID Nummer verändert. Si sollte daher als private deklariert werden. Zusätzlich soll ein neuer Konstruktor geschaffen werden, der bereits den Namen und den umkreisten Körper enthält. public class Planet { public long id; public String name; public Planet orbit; private static long naechsteID = 0; // nur Klasse Planet hat // Zugriff Planet() {id = naechsteID++ } // Konstruktor 1 Planet(String planetName, Planet orbitName ) { id = naechsteID++ ; // Konstruktor 2 name = planetName; orbit = orbitName; } } Alternativ mit this: Planet(String planetName, Planet orbitName ) { this(); // expliziter Aufruf Konstruktor 1 name = planetName; orbit = orbitName; Neues Hauptprogramm (mit Parameter - Konstruktor) } 841119650 -3- Java FH Merseburg SS 2002 public class Control { public static void main(String[] args) { Planet sonne = new Planet(„Sonne“, null); Planet erde = new Planet(„Erde“, Sonne); Utilities wait; ... // waitForReturn } } 2.3.4 Datenkapselung Methodeneinsatz zur Zugriffskontrolle: public class Planet { private long id; public String name; public Planet orbit; private static long naechsteID = 0; Planet() {id = naechsteID++; } Planet(String planetName, Planet orbitName ) { this() ; name = planetName; orbit = orbitName; } // Konstruktor 1 // Konstruktor 2 public void setid (long idWert) { id = idWert; } public long getid() {return id;} } Neues Hauptprogramm: public class Control { public static void main(String[] args) { Planet sonne = new Planet(„Sonne“, null); Planet erde = new Planet(„Erde“, Sonne); sonne.id = Planet.naechsteID++; // unzulässig sonne.setid (7); Utilities wait = new Utilities; ... // waitForReturn } } 841119650 -4- Java FH Merseburg SS 2002 Andere Methoden public class Planet { private long id; public String name; // könnte auch private sein public Planet orbit; // könnte auch private sein private static long naechsteID = 0; // Konstruktoren // Planet() Planet(String planetName, Planet orbitName )) // Zugriffe // public void setid (long idWert) public long getid() public ausgabeAttribute (){ System.out.println(„Planet: „ + \u0009 + name); System.out.println(„ID Nummer: „ + \u0009 + name); System.out.println(„Umkreist: „ + \u0009 + orbit); } } Hauptprogramm: public class Control { public static void main(String[] args) { Planet sonne = new Planet(„Sonne“, null); Planet erde = new Planet(„Erde“, Sonne); sonne.setid (7); sonne.ausgabeAttribute(); erde.ausgabeAttribute(); Utilities Wait = new Utilities; ... // waitForReturn } } Jede Methode hat eine definierte Anzahl von Parametern (keine variable Anzahl). Alle Parameter haben einen Typ (primitiver oder Referenztyp) und die Methoden haben einen Rückgabewert (Signatur). Erzeugen eines Strings, der Planeten beschreibt: public String toString() { String beschreibung = id + „ ( „ + name + „ ) „ ; If (orbit != null) Beschreibung += „ Orbit: „ + orbit.toString(); Return beschreibung; } Enthält eine Instanz eine parameterlose Methode toString(), die einen String zurückliefert, wird sie zur Erzeugung eines Strings aufgerufen, sobald das Objekt in Zeichenkettenverbindung benutzt wird. System.out.println(„Planet: “ + erde) 841119650 -5- Java FH Merseburg SS 2002 Erde ist in diesem Fall der Name einer Instanz der Klasse Planet. Diese Instanz erzeugt folgenden String: Planet: 1 (Erde) Orbit: 0 (Sonne) Die Anweisung orbit.toString ist eine Rekursion ! // Parameter – mehrere Ergebnisse zurückgeben This This ist eine spezielle Objektreferenz, die sich auf das aktuelle Objekt bezieht. public class Planet { private long id; public String name; public Planet orbit; private static long naechsteID = 0; Planet() {id = naechsteID++; } Planet(String name, Planet orbitName ) { this(); // ruft den parameterlosen Konstruktor // derselben Klasse auf this.name = planetName; //spezifiziert Instanzvariable name orbit = orbitName; } // ..weitere Methodendefinitionen } This wird auch verwendet in objektbezogenen Methoden und nicht nur für Konstruktoren. Ebenso wird this verwendet, um eine Referenz an das aktuelle Objekt als Parameter an andere Methoden weiterzugeben. Liste.add(this); //Methode fügt Objekt in eine Liste ein Innerhalb einer Methode wird jeder Variablen- oder Methodenreferenz this implizit vorangestellt, wenn es nicht explizit angegeben wird. class Name { String str; name() {str = „Mueller“;} } // this.name = „Mueller“ This wird jedoch nur verwendet, wenn der Variablenbezeichner, auf den zugegriffen werden soll, durch einen Parameter abgeschattet wurde siehe oben super für den Zugriff auf verborgene Variablen *** 841119650 -6-