Björn Klippstein

Generalisierung

Klippstein IT Service

Aus 4webmaster.de

Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

Die Generalisierung / Spezialisierung ist eine Relation zwischen zwei Klassen, zwischen Subklasse und Superklasse. Die Superklasse ist allgemein, die Subklasse speziell. Mathematisch entspricht die Generalisierung der Teilmengen-Relation und die Spezialisierung der Obermengen-Relation.

Jedes Exemplar der Subklasse ist auch ein Exemplar der Superklasse. Die Generalisierung / Spezialisierung ist transitiv.

Im Gegensatz zur Assoziation, die Interaktionsbeziehungen zwischen den konkreten Objekten zweier Klassen repräsentiert, handelt es sich bei der Generalisierung / Spezialisierung um eine Relation zwischen zwei Klassen.

In UML wird die Generalisierung / Spezialisierung durch einen Pfeil mit nicht ausgefüllter Pfeilspitze dargestellt. Die Spitze weist dabei auf die Superklasse. Optional kann der Pfeil nach dem Unterscheidungsmerkmal benannt und beschriftet werden (Generalisierungsmenge / Diskriminator).


Generalisierung / Spezialisierung
Generalisierung / Spezialisierung in UML

Generalisierung / Spezialisierung
Generalisierung / Spezialisierung mit Diskriminator




Vererbung

Mit Hilfe des Mechanismus der Vererbung können die Attribute, Assoziationen und Methoden einer Superklasse von einer Subklasse genutzt werden. So können gemeinsame Eigenschaften der Subklassen in einer Superklasse zusammengefasst werden.

Bei der Erzeugung eines Subklassen-Objektes wird erst der Konstruktor der Superklasse aufgerufen und danach der Konstruktor der Subklasse. Bei der Zerstörung eines Objektes ist es genau umgekehrt: Zunächst wird der Destruktor der Subklasse aufgerufen, dann der der Superklasse.




Schnittstellen

Eine Schnittstelle ist das nach außen Sichtbare einer Komponente. Oft wird für ähnliche Klassen eine gemeinsame Schnittstelle angelegt. Dazu gibt es in Java zwei Möglichkeiten:

Abstrakte Klasse: Die ähnlichen Klassen erben Methoden von einer abstrakten Klasse
Interface: Die ähnlichen Klassen implementieren das gleiche interface



Abstrakte Klasse

Eine abstrakte Klasse dient nur zur Vererbung ihres Inhaltes. Sie kann keine eigenen Instanzen haben. So wird sie deklariert:

abstract class MeineSchnittstelle {
 
  // diese Methode ist direkt für alle Instanzen der Subklassen einsatzfähig
  public void nutzeMichSofort() {
    ..
    .. 
  }
 
  // diese Methode ist abstrakt, d.h. sie ist nicht implementiert,
  // sondern existiert nur als Methodenkopf.
  // Abstrakte Methoden *müssen* von allen Subklassen implementiert werden.
  public abstract void implementiereMichErst();
 
}

Da in Java eine Klasse nur von einer einzigen Superklasse erben kann, ist die Nutzbarbeit abstrakter Klassen recht beschränkt. Aber so wird sie eingesetzt:

class MeineKlasse extends MeineSchnittstelle {
 
  // Implementierung der geforderten Methode
  public void implementiereMichErst() {
    ..
    ..        
 }
 
}



Interface

Ein Interface erzwingt die Implementierung bestimmter Methoden in einer Klasse. Interfaces haben natürlich auch keine Instanzen. Beispiel einer Schnittstellendeklaration:

interface IMeineSchnittstelle {
 
  // Alle hier deklarierten Methoden sind public und abstract, 
  // daher können die Schlüsselwörter weggelassen werden. 
  void implementiereMichErst();
 
}


class MeineKlasse extends WhatEver implements IMeineSchnittstelle {
 
  // Implementierung der geforderten Methode
  public void implementiereMichErst() {
    ..
    ..        
 }
 
}



Verwendung von Schnittstellen

Schlecht: Auf eine Implementierung programmieren:

Pferd ferdi = new Pferd();
ferdi.reiten();

Besser: Auf eine Schnittstelle programmieren:

Tier tirtir = new Pferd();
tirtir.fortbewegen();

Noch besser: Das Factory-Muster zur Objekterzeugung nutzen:

tirtir = getTier();
tirtir.fortbewegen();




Darstellung von Schnittstellen in UML

Abstrakte Klassen und Interfaces werden in UML wie Klassen dargestellt, nur sind die Namen kursiv. Abstrakte Methoden werden ebenfalls kursiv dargestellt. Interfaces werden zusätzlich mit dem Stereotyp «Interface» gekennzeichnet, außerdem werden die Generalisierungspfeile unterbrochen dargestellt.

Mit dem hier verwendeten Tool (Graphviz) ist eine genau standardkonforme Darstellung nicht möglich. Das folgende Diagramm zeigt die wesentlichen Merkmale der UML-Darstellung:


Abstrakte Klasse
Abstrakte Klasse

Interface
Interface





Kapselung

Der Zugriff auf Attribute und Methoden eines Objektes kann durch Kapselung eingeschränkt werden, um das Geheimnisprinzip / Information Hiding zu realisieren: Alle Details, die nicht zur konkreten Verwendung notwendig sind, sollen dem Nutzer (das ist i.d.R. ein anderes Objekt) verborgen bleiben.

Dabei können die Daten eines Objektes nur mit den Methoden des Objektes selbst gelesen und geschrieben werden. Nach außen hin sind die Attributwerte dann unsichtbar. Der direkte Zugriff auf die interne Datenstruktur wird unterbunden und erfolgt statt dessen über definierte Schnittstellen (Setter- und Getter-Methoden).

Die Kapselung dient der Realisierung auswechselbarer Komponenten. Das Gesamtsystem kann, wenn alles gut gekapselt ist, durch den Austausch von Komponenten aktualisiert werden.

Beispiel: Das Y2K-Problem war überall dort sehr einfach zu lösen, wo das Datum konsequent in ein Datumsobjekt gekapselt war. Man brauchte nur dieses Datumsobjekt aktualisieren, der Rest der Software igoriert die Implementationsdetails des Datums.

Sichtbarkeit

Schlüsselwort (Java) UML-Notation Wer kann zugreifen?
public + Jeder ─ der Zugriff ist nicht eingeschränkt und auch von außen möglich.
private - Nur für Objekte der gleichen Klasse ─ der Zugriff ist nur innerhalb der Klasse möglich.
protected # Wie private, zusätzlich ist auch den Objekten der Unterklassen der Zugriff erlaubt
(keines) ~ Wie public, aber nur innerhalb des eigenen Paketes. Dies ist der Standardwert in Java. In C# wird diese Sichtbarkeit mit dem Schlüsselwort internal gekennzeichnet, in C++ und VB mit friend.
static (unterstrichen) Das Element ist auch ohne Objekt sichtbar und zugreifbar (ein Klassenattribut oder eine Klassenmethode). Das Schlüsselwort static wird zusätzlich zu den anderen Sichtbarkeitsschlüsselwörtern notiert (dahinter).

Kapselung realisieren

  • Attribute stets private oder protected deklarieren
  • public Getter- und Setter-Methoden für alle nach außen sichtbaren Attribute erstellen
  • Auch für die rein intern verwendeten Attribute Getter- und Setter-Methoden erstellen (private oder protected), um den Datenzugriff zentral zu bündeln






Siehe auch