Freie Scripten und Tutorials erstellt von Roland Geyer       Startseite | Gästebuch

Vererbung

Eine Vererbung ist eine Beziehung zwischen Klassen. Die Beziehung lautet: Diese Klasse ist vom Typ der anderen Klasse. Sie bedeutet eine ODER-Relation bei einer Zusammensetzung.

Eine Beziehung zwischen Klassen wird mit extends festgelegt.

Beispiel: die Abgeleitete Klasse erweitert die Basisklasse:
public class A extends B

B asisklasse
A bgeleitete Klasse von der B asisklasse.

Alles was der Erbe nicht nennt, wird vom Beerbenden übernommen:

Methoden die geerbt werden, braucht man daher nicht neu zu nennen.

class Vater
    String familienName;
    string vorName;
 
    Vater(String parameter){
        familienName = parameter;

    }

    public void setVorname(String parameter){
        vorname = parameter;
    }
    public String getFamilienName(){
        return familienName;
    }

    public String getVorName(){
        return VorName;
    }
}

class Sohn extends Vater{
}

public class Start{
    public static void main(String[] args){
        Sohn roland = new Sohn("Geyer");
        roland.setVorName("Roland");
        System.out.println(roland.getVorName);      
    }
}


Jede Klasse muß einen eigenen Konstruktor enthalten. Wird kein Konstruktor im Erbe angegeben, wird der Konstruktor des Erben genommen, der keine Parameter enthält. Achtung: Wurde in der zu erbenden Klasse mindestens ein Konstruktor definiert, wird KEIN Standardkonstruktor in dieser Klasse erzeugt! Daher kann auch keiner weitervererbt werden!

Obwohl nicht angegeben, leitet sich jede Klasse in Java von der Klasse Object ab. API: java.lang.Object

Der Aufruf geerbter Konstruktoren oder Methoden erfolgt durch super.
Wird der geerbte Konstruktor aufgerufen, muss diese Anweisung in der ersten Zeile des Konstruktors stehen.

Beispiel:

MyKlass(parameter,neuerParameter){
super(parameter);
neu = neuerParameter;
}

Genauso erfolgt der geerbte Methodenaufruf:

Beispiel:

public int doppeltGehalt(){
gehalt = super.einfachGehalt();
doppeltGehalt = 2*gehalt;
return doppeltGehalt;
}

Beispiel_1.5: Datei: Mercedes.class

import Fahrzeug
 
class Mercedes extends Fahrzeug{
/////////////////Implementierung/////////////////////////////////
//Instanzvariablen
    privat String farbe;
    privat int liter;
    privat int geschwindigkeit;

	
//Konstruktor
	Mercedes(String parameter1, int parameter2){
	    super ( parameter1,parameter2); //####farbe + liter GEERBT
        int geschwindigkeit = 0;
	}
	
//Methoden	der Klasse Fahrzeug
	private void beschleunigen(int gibGas){
		geschwindigkeit = super(geschwindigkeit) + 50;
	}

///////////////////Schnittstelle////////////////////////////////
//setter Methoden	
	public void setMyGeschwindigkeit(int pMyGeschwindigkeit){
		geschwindigeit = pMyGeschwindigkeit;
	}
	
//getter Methoden
	public String getFarbe(){
    	super.getFarbe();//#################GEERBT
	}

	public int getMyliter(){
	    return liter;
	}	
	public int getMyGeschwindigkeit(){
	    return geschwindigkeit;
	}

}



Super-Klassen können ihre Fähigkeiten an ihre sub-Klassen weitergeben. Da sub-Klassen diese Fähigkeiten nicht nur erben, sondern auch weiterentwickeln können, spricht man auch von Generalisierung und/oder Spezialisierung, je nach Sichtweise in der Vererbungslinie.

Entscheidend ist, welches Attribut generalisiert wird. Es soll nur eine Eigenschaft pro Hierachie generalisiert werden. Eine entstehende Unterklasse ist ein Spezialfall der Oberklasse. Eine Klasse soll ihre Art, nicht aber ihre Rolle spezialisieren. Eine neue Rolle soll besser durch Komposition entstehen!!

Basisklassen sollen unveränderbar sein, denn erben bedeutet auch, dass der Typ geerbt wird!!! Wichtig wäre, dass die Klassen einer Hierachie daher die Schnittstelle nicht ändern. Werden Änderungen der Schnittstelle in der spezialisierten Klasse durchgeführt, muss nach der Typenumwandlung in die Klasse, die dies zur Verfügung stellt, der geänderte Typ genannt werden! Ist der Wert ein elementarer Datentyp ist damit die Sache erledigt. Zwischen Objekten funktioniert das nur innerhalb der Vererbungshierachie. Da die Subklasse mit einem Datentyp der Superklasse, die angeblich erweitert wurde nichts anfangen kann, können nur Typen der generalisierten Klasse auf Typen der spezialisierenden Klasse, die ja den generalisierten Typ enthält umgewandelt werden (im weiteren Sinne: auf den Typ der Spezialklasse verallgemeinern). Dies geschieht durch Nennung der Klasse, eingeschlossen zwischen zwei runden Klammern, vor Aufruf des Objektes.

Beispiel zum Diagramm:
Einen Unbeschäftigten anlegen:
Unbeschäftigt person1 = new Unbeschäftigt();
person1.setName = "roland";
// jetzt umwandeln:
Jetzt benötige ich den Typ Person: (Person) person1.getName();

weitere Beispiele siehe API: java.awt, API: javax.swing

Ein Vorteil der Vererbung liegt in der Wiederverwendung bestehender Ressourcen

Die Unterklasse kann den privaten Teil der Oberklasse sich antypisieren, nicht jedoch auf die Werte dieser Attribute zugreifen!!

Änderungen an der Wurzel einer Vererbungshierachie beeinflussen alle erbenden Klassen dieser Hierachie!

Im schlimmsten Fall bewirkt eine Methode ganz was anderes. Damit müssen ALLE erbenden Klassen entsprechend verändert werden!!! = Hauptnachteil der Vererbung! Das System kann unüberschaubar mit zuvielen Abhängigkeiten versehen werden.

Um das einzuschränken kann man nur die Methodennamen und die Signatur der Methode = Schnittstelle der Klasse ohne Implementierung festlegen. Das bedeutet, dass diese Klasse nur abstrakte Methoden zur Verfügung stellt. Auf diese Weise kann man eine gemeinsame Schnittstelle der gesamten Klassenhierachie festlegen unabhängig von der tatsächlich implementierten Methode.

Eine abstrakte Methode wird durch abstract definiert, ist immer public und beinhaltet keinen Methodenrumpf:

public abstract void eineOperation();

Wenn Merkmale zu organisieren sind, die in der Klassenerbfolge zwingend implementiert werden müssen, können sie als abstrakte Klasse definiert werden.

Abstrakte Operationen können nur in abstrakten Klassen definiert werden. Abstrakte Klassen können auch nicht abstrakte Teile enthalten!

Durch final vor Namensnennung einer Deklaration (Variable, Methode, Konstruktor, Klasse) kann eineVererbung und die damit verbundenen Möglichkeit einer Überschreibung (Sicherheit!!) bzw. dynamischen Bindung verhindert werden. In einer finalen Klasse ist natürlich alles bereits final! Da bei final die gesamte Vererbungskette nicht durchsucht werden muss, wird die Durchführung des Codes beschleunigt.

Durch einen private Konstruktor kann ein Vererbungsversuch unterbunden werden!

Static legt fest, das es nur ein einmaliges Vorkommen gibt!

Die Nachteile einer Vererbung können durch die Verwendung einer Hüllenklasse statt der Vererbung aufgehoben werden:

interface Vater

    public void setVorname(String parameter){}
    public String getFamilienName(){}

    public String getVorName(){}
}

class Sohn implements Vater{
    private final Vater vomVater;

    String familienName;
    string vorName;

    public Sohn(Vater instanz){
        vomVater = instanz;
    }

    public void setVorname(String parameter){
        vomVater.setVorname(String parameter);
        vorname = parameter;
    }
    public String getFamilienName(){
        vomVater.getFamilienName();
        return familienName;
    }

    public String getVorName(){
        vomVater.getVorName();
        return VorName;
    }
}
Weitere freie Tutorials: Rhetorik & Kommunikation Typografie & Layout Bildbearbeitung mit Photoshop oder GIMP Vektorgrafik mit Illustrator, FreeHand, Corel Draw oder Inkscape Layout mit Indesign oder Scribus Druckvorstufe GoLive Html JavaScript Flash & ActionScript Director & Lingo Assembler DOS Java objektorientiert Perl Word Excel Access PowerPoint Outlook Betriebssystem