Info B VL 4: Konstruktoren und Vererbung
Objektorientiere Programmierung in Java 2003
Ute Schmid (Vorlesung) Elmar Ludwig ( ¨ Ubung)
FB Mathematik/Informatik, Universit¨at Osnabr¨uck
Konstruktoren
Spezielle Funktion zur Erzeugung von Objekten Ursprünglich: in funktionaler Programmierung und Typtheorie als Symbol zur Erzeugung eines
algebraischen Datentyps Beispiel in ML:
datatype ’a list = nil | :: of ’a * ’a list
Ausdrücke, die nur Konstruktoren enthalten sind in Normalform (werden nicht weiter
ausgewertet/reduziert)
Funktionen über algebraischen DTs können pattern matching verwenden:
fun f(nil) = nil
| f(x::l) = if even(x) then f(l) else x::f(l);
Info B VL 4: Konstruktoren und Vererbung – p.84
Konstruktoren in OO-Sprachen
mit C++ eingeführt
Konstruktor wird von einer Klasse zur Verfügung gestellt und dient der Initialisierung eines Objekts
da neue Objekte meist über Konstruktoraufruf erzeugt werden kann Initialisierung nicht vergessen werden
In C++ und Java: Konstruktornamen gleich Klassennamen
In C++: Destrukturen als Gegenstück (Freigabe von Ressourcen)
In Java kaum notwendig wegen Garbage Collector
Konstruktor-Definition
Konstruktoren haben keinen Rückgabetyp (auch nicht void )
Wird für eine Klasse kein Konstruktor definiert, so wird ein Default Konstruktor (auch “no-arg constructor”)
angelegt
Der Default Konstruktor hat keine Argumente
Alle Konstruktoren haben implizit eine Referenz zum neu erzeugten Objekt ( this ) als Argument
Im Konstruktor-Körper werden die Initialisierungen des this -Objekts vorgenommen.
Beispiel: Initialisierung eines Circle -Objekts
public Circle(double r) { this.r = r; } ...
Circle c = new Circle(2.0);
Info B VL 4: Konstruktoren und Vererbung – p.86
Definition mehrerer Konstruktoren
Möglichkeit, Objekt auf verschiedene Art zu initialisieren
public Circle() { r = 1.0; }
public Circle(double r) { this.r = r; }
Wie bei Methoden gilt overloading: gleicher Name aber unterschiedliche Signaturen (Anzahl und Typ der
Argumente)
Ein Konstruktor kann andere Konstruktoren aufrufen:
this() als Konstruktoraufruf; welcher Konstruktor aktiviert wird, hängt wieder von Anzahl und Typ der Argumente ab.
Verwendung von this() ist gute Strategie, wenn die Konstruktoren Teile der Initialisierung gemeinsam
haben
this() darf nur als erste Anweisung in einem
Konstruktor vorkommen Info B VL 4: Konstruktoren und Vererbung – p.87
Beispiel ‘Circle’
// This is the basic constructor:
// initialize the radius
public Circle(double r) { this.r = r; } // This constructor uses this() to invoke // the constructor above
public Circle() { this(1.0); }
Info B VL 4: Konstruktoren und Vererbung – p.88
Default Werte
Lokale Variablen (innerhalb von Methoden definiert) haben keine Default-Werte
Werden lokale Variablen nicht vor ihrer Verwendung initialisiert, liefert der Java-Compiler eine
Fehlermeldlung!
(Klassen- und Instanz-) Felder sind automatisch mit Default-Werten initialisiert
Übliche Deklaration mit Zuweisung eines initialen Wertes ist ebenfalls möglich
public static final double PI = 3.14159;
public double r = 1.0;
Default Werte für Felder
Typ Default
boolean false
char ‘ u0000’
byte , short , int , long 0 float , double 0.0
reference null
Info B VL 4: Konstruktoren und Vererbung – p.90
Initialisierung von Instanz-Feldern
Konstruktoren
Java Compiler erzeugt Initialisierungscode für
Instanz-Felder und fügt sie in Konstruktor(en) ein
Reihenfolge: die im Programm angegebene (Nutzung von bereits initialisierten Feldern bei der Initialisierung weiterer Felder möglich)
Wenn ein Konstruktor mit this() Anweisung beginnt, dann wird in diesen Konstruktor die Initialisierung nicht eingefügt, sondern in denjenigen Konstruktor, der
durch this() aktiviert wird
ab Java 1.1: Initialisierungsblöcke für Instanz-Felder:
...
, die an beliebiger Stelle (an der
Komponenten stehen können) in die Klasse eingefügt
werden können; üblich: direkt nach Feld; benutzt vor
allem für anonyme innere Klassen
Beispiel
public class TestClass { public int len = 10;
public int[] table = new int[len];
public TestClass(){
for (int i = 0; i < len; i++) table[i] = i;
} }
Ist äquivalent zu
public class TestClass { public int len;
public int[] table;
public TestClass() { len = 10;
table = new int[len];
for (int i = 0; i < len; i++) table[i] = i;
} } Info B VL 4: Konstruktoren und Vererbung – p.92
Initialisierung von Klassen-Feldern (1)
Statische Initialisierungs-Bl ¨ocke
Klassen-Felder existieren auch wenn kein Objekt erzeugt wird
Initialisierung vor Konstruktoraufruf notwendig
Java Compiler erzeugt
Klassen-Initialisierungs-Methode (interne, versteckte Methode clinit
), in der alle Klassen-Felder
initialisiert werden.
Diese Methode wird genau einmal ausgewertet, nämlich wenn die Klasse das erstemal benutzt (geladen) wird.
Initialisierung wieder in der im Programm
angegebenen Reihenfolge
Init. von Klassen-Feldern (2)
Explizite Initialisierung von Klassen-Feldern mit static initializer Block: static ...