3 Häufig gepostete Fragen

3.1 [LANG] Die Sprache Java

3.2 [STRING] Strings

3.3 [IO] Eingabe/Ausgabe, Streams, etc.

3.4 [NET] Netzwerk

3.5 [AWT] Abstract Window Toolkit

3.6 [SWING] Swing, das bevorzugte GUI

3.7 [APPLET] Java-Applets und ihre Zusammenarbeit mit Browsern

3.8 [SERVER] Servlets und andere Server-Implementierungen in Java

3.9 [NONCORE] Klassen/Packages, die über den Kern der Sprache hinausgehen, also Java3D etc.

3.10 [OOP] OOP-Konzepte und Patterns in Java

3.11 [JDK] Virtuelle Maschinen, alles über JDKs und deren Installation und Verwendung

3.12 [TOOLS] Java-Zusatz-Tool, zum Beispiel IDEs, Build-Tools, Profiler, etc.

3.13 [MISC] Alles, was nicht in eine der anderen Rubriken paßt

3.14 [ERROR] Fehlermeldungen


3.10 [OOP] OOP-Konzepte und Patterns in Java

Zurück zu "3 Häufig gepostete Fragen"

3.10.1 Was bedeutet Vererbung im OO-Kontext?

Vererbung ist in Java, und natürlich auch in anderen Programmiersprachen, nur eine Möglichkeit, um das konkrete Problem in den Computer zu übertragen. Das Prinzip der Vererbung ist dann anwendbar, wenn zwei Objekte in einer ist-ein oder ist eine Art von Beziehung zueinander stehen. Eine abgeleitete Klasse ist ein Subtyp der zugehörigen Oberklasse, besitzt also deren Eigenschaften (Daten & Methoden) und erweitert diese bei Bedarf um neue. LKW und PKW sind zum Beispiel Subtypen der Oberklasse Automobil, wobei beim LKW zum Beispiel die maximal zulässige Anhängerlast oder die Achsenanzahl hinzukommt.

Wendet man das Prinzip der Vererbung an, so gilt das sogenannte Liskov'sche Substitutionsprinzip:

Objekte der abgeleiteten Klasse können stets an die Stelle von Objekten der Oberklasse treten.

Autor: Markus Reitz

Zurück zu "3.10 [OOP] OOP-Konzepte und Patterns in Java"

3.10.2 Was bedutet Aggregation im OO-Kontext?

Das Prinzip der Aggregation besagt, daß ein Objekt aus mehreren Teilen (=Objekten) besteht, die wiederrum aus Teilen bestehen können usw. Die Klasse Computer könnte z.B. aus den Klassen Speicher, Festplatte etc. bestehen. In einem Pseudo-Java-Code etwa so formuliert:

public class Computer {
    private Speicher rom;
    private Speicher ram;
    private Speicher festPlatte;

    (...)
}

Autor: Markus Reitz

Zurück zu "3.10 [OOP] OOP-Konzepte und Patterns in Java"

3.10.3 Was bedeutet Assoziation im OO-Kontext?

Mit der Assoziation wird die Verbindung des Objektes zu einem oder mehreren anderen Objekten beschrieben. Assoziationen können kurzfristig sein, zum Beispiel dann, wenn ein anderes Objekt an das aktuelle Objekt als Parameter der Objektmethode übergeben wird. Sie können aber auch langfristig sein, wenn das Objekt Referenzen auf die assoziierten Objekte speichert (Registrierung).

Autor: Markus Reitz

Zurück zu "3.10 [OOP] OOP-Konzepte und Patterns in Java"

3.10.4 Was bedeutet Benutzung im OO-Kontext?

Das aktuelle Objekt benutzt eines oder mehrere andere Objekte um die anstehende Aufgabe erfüllen zu können. Das Objekt Backofen benutzt zum Beispiel das Objekt Thermostat, um die Aufgabe backen zu erfüllen, damit der Inhalt des Backofens nicht verkohlt.

Es muß angemerkt werden, daß man häufig aus dem Programmcode keine direkte Entscheidung treffen kann, ob Aggregation, Assoziation oder Benutzung vorliegt. Diese drei Beziehungen sind prinzipiell Designprinzipien, die in der späteren Implementierungsphase, zum Beispiel in Java, in relativ ähnliche oder sogar identische Konstrukte umgesetzt werden. Es ist deshalb wichtig, daß man das jeweils zugrunde gelegte Prinzip dokumentiert, damit die Funktionsweise besser und einfacher nachvollzogen werden kann.

Autor: Markus Reitz

Zurück zu "3.10 [OOP] OOP-Konzepte und Patterns in Java"

3.10.5 Worin liegen die Unterschiede zwischen abstrakten Klassen und Interfaces?

Java fügt dem schon von C++ her bekannten Konzept der abstrakten Klasse noch ein weiteres, aus der Sprache Objective-C entliehenes Feature hinzu: Interfaces. Ein Interface ist zuersteinmal nichts anderes als eine Auflistung von Methoden. Eine Klasse implementiert ein Interface, wenn sie alle in der Interface-Deklaration angegebenen Methoden besitzt. Wird mindestens eine der Methoden des Interfaces nicht implementiert, so wird die Klasse zu einer abstrakten Klasse. Mit dem Interface-Prinzip lassen sich in Java einfach Benutzt-Beziehungen modellieren. Eine Klasse benutzt eine andere Klasse in dem Sinn, daß es ganz spezielle Methoden dieser Klasse verwendet, um seine eigene Funktionalität zu realisieren - auf Daten der Hilfsklasse wird ja wegen dem Prinzip der Datenkapselung nicht direkt zugegriffen. Um ein Objekt zu benutzen, ist es nur wichtig, daß dieses Objekt die gewünschten Funktionen auch besitzt. Man definiert sich daher ein Interface, welches die benötigten Funktionen auflistet. Alle Objekte, die diese Funktionen benötigen, sprich, die dieses Interface verlangen, können nun all die Klassen verwenden, die dieses Interface implementieren. Im Sinne eines guten Klassendesigns ist es daher wichtig, solche Benutzt-Beziehungen zu lokalisieren, um die Klassen flexibler zu machen und unnötigerweise angewendete Vererbung zu eliminieren. Abstrakte Klassen sind im Gegensatz dazu Modellierungen des Ist ein-Prinzips und unterscheiden sich in dieser Hinsicht von Interfaces.

Autor: Markus Reitz

Zurück zu "3.10 [OOP] OOP-Konzepte und Patterns in Java"

3.10.6 Was ist eine anonyme innere Klasse?

Eine anonyme innere Klasse trägt keinen Namen und wird vor allem bei der GUI-Programmierung für Adapterklassen verwendet. Wird eine solche Klasse in ein Class-File übersetzt, so werden alle anonymen Klassen, die in der umgebenden Klasse definiert wurden, von Null beginnend durhnummeriert.

    Testklasse$0.class

ist also das Class-File der ersten in der Klasse Testklasse auftauchenden anonymen inneren Klasse.

Autor: Markus Reitz

Zurück zu "3.10 [OOP] OOP-Konzepte und Patterns in Java"

3.10.7 Was ist ein immutable Objekt?

Ein immutable (unveraenderliches) Objekt ist ein Objekt, das nach seiner Instanzierung nicht mehr veraendert werden kann. Bekannte Beispiele hierfuer sind saemtliche Wrapper-Klassen (Integer, Boolean,... ) sowie die Klasse String.

Dieses Design-Pattern bietet folgende Vorteile:

Immutable Objekte muessen folgende Forderungen erfuellen:

(*) Klonen ist hier in der Bedeutung "tief genug kopieren" gemeint: Es muessen rekursiv alle mutable Attribute kopiert werden. Dies hoert sich komplizierter an, als es in der Praxis ist, da die verwendeten Objekte i.d.R. nicht verschachtelt sind, reicht meist eine flache Kopie aus.

Beispiel:

public class MyImmutable {
    public  final int i;
    private final String s;
    private final int[] a;
    private final Point p;

    public MyImmutable(int i, String s, int[] a, Point p) {
        this.i = i;                  // primitiver Typ ist immutable
        this.s = s;                  // String ist immutable
        this.a = new int[a.length];  // Arrays sind mutable!
        System.arraycopy(a, 0, this.a, 0, a.length);
        this.p = new Point(p);       // Point ist mutable!
    }

    public String getS() {
        return s;
    }

    // Array ist mutable, also Klon zurueckgeben
    public int[] getA() {
        return (int[]) a.clone();
    }

    // alternativ: Elementzugriff, die int-Elemente sind immutable
    public int getAAt(int pos) {
        return a[pos];
    }

    // Point ist mutable, also Klon zurueckgeben
    public Point getP() {
        return new Point(p);
    }
}

Zusaetzlich ist folgendes zu beachten:
Subklassen von Immutables muessen selbst nicht immutable sein und koennen im schlimmsten Fall sogar das Konzept unterlaufen!

Beispiel:

public class AntiImmutable extends MyImmutable {
    public String s;

    public AntiImmutable(int i, String s, int[] a, Point p) {
        super(i, "", a, p);
        this.s = s;
    }

    public String getS() {
        return s;
    }
}

    MyImmutable mi = new AntiImmutable(0, "A", anIntArray, new Point(0, 0));
    ((AntiImmutable)mi).s = "B";
    System.out.println(mi.getS());

--> Ergibt "B"!!!

Daher ist es meist angebracht, Immutables final zu deklarieren! Zudem sollte man Attribute, die zwar immutable, aber nicht final sind, wie Mutables behandeln (also im Konstruktor bzw. bei der Rueckgabe klonen).

Autor: Gerhard Bloch

Zurück zu "3.10 [OOP] OOP-Konzepte und Patterns in Java"