Vererbung: Unterschied zwischen den Versionen

Aus EINI
Wechseln zu: Navigation, Suche
(Verwendung)
 
(15 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
Unter '''Vererbung''' bezeichnet man das Konzept zwischen verschiedenen Klassen eine '''ist ein''' Beziehung herzustellen. Hauptsächlich wird Vererbung verwendet um Zeit zu sparen und Code einfacher zu gestalten, wenn mehrere Klassen sehr ähnliche Funktionalitäten bereitstellen sollen. Das Erben von mehr als einer Klasse ist in Java nicht möglich. Eine erbende Klasse wird auch '''Unterklasse''', die vererbte Klasse entsprechend '''Oberklasse''' genannt.
+
Unter '''Vererbung''' bezeichnet man das Konzept, zwischen verschiedenen [[Klasse|Klassen]] eine "'''ist ein'''"-Beziehung herzustellen. Hauptsächlich wird Vererbung verwendet, um Zeit zu sparen und Code einfacher zu gestalten, wenn mehrere Klassen sehr ähnliche Funktionalitäten bereitstellen sollen. Das Erben von mehr als einer Klasse ist in [[Java]] nicht möglich. Eine erbende Klasse wird auch '''Unterklasse''' oder '''Subclass''', die vererbte Klasse entsprechend '''Oberklasse''' oder '''Superclass''' genannt.
  
 
= Deklaration =
 
= Deklaration =
Zeile 9: Zeile 9:
 
= Verwendung =
 
= Verwendung =
  
Eine erbende Klasse besitzt alle [[Attribute]] und [[Methoden]] der Oberklasse. Direkt aufrufen kann die erbende Klasse jedoch wie jede andere Klasse auf keine [[private|privaten]] Methoden oder Attribute der Oberklasse direkt zugreifen. Sie können jedoch auf [[protected|beschützte]] Attribute und Objekte zugreifen.
+
==Erläuterung==
 +
 
 +
Eine erbende Klasse besitzt alle [[Attribut|Attribute]] und [[Methode|Methoden]] der Oberklasse. Die erbende Klasse kann zwar direkt aufrufen, hat aber, wie jede andere Klasse auch, keinen direkten Zugriff auf die [[private|privaten]] Methoden oder Attribute der Oberklasse. Sie kann jedoch auf [[protected|beschützte]] Attribute und Objekte zugreifen.
  
 
Erbende Klassen können zudem Methoden der Oberklasse überschreiben. Dabei wird einfach die gesamte Signatur der zu überschreibenden Methode bei der Deklaration der überschreibenden Methode übernommen.
 
Erbende Klassen können zudem Methoden der Oberklasse überschreiben. Dabei wird einfach die gesamte Signatur der zu überschreibenden Methode bei der Deklaration der überschreibenden Methode übernommen.
  
All dies wird getan um in [[Sammlung]]en von Objekten einer Oberklasse verschiedene Objekte unterschiedlicher Unterklassen zu sammeln und das verhalten verschiedener Methodenaufrufe von den Unterklassen abhängig zu machen, ohne sich selbst jedoch um die entsprechende Implementierung kümmern zu müssen.
+
All dies wird getan, um in [[Sammlung|Sammlungen]] von [[Objekt|Objekten]] einer Oberklasse verschiedene Objekte unterschiedlicher Unterklassen zu sammeln und das Verhalten verschiedener Methodenaufrufe von den Unterklassen abhängig zu machen, ohne sich jedoch selbst um die entsprechende Implementierung kümmern zu müssen.
  
== Beispiele ==
+
Implizit erbt '''jede''' Klasse in Java automatisch von der Klasse '''Object'''. Die Methoden dieser Klasse sind jedoch selten wirklich hilfreich implementiert. So vergleicht <code>.equals(...)</code> nur die Referenzen der übergebenen Objekte miteinander, nicht aber deren Inhalt. <code>.toString()</code> gibt nur einen pseudo-zufällig generierten [[String]] zurück, der das Objekt identifizieren kann, jedoch keinerlei hilfreiche Informationen enthält. Entsprechend sollten diese Methoden bei Bedarf überschrieben werden.
 +
 
 +
== Beispiel ==
 +
 
 +
Ein geometrisches Objekt beschreibt etwas, das in einem Raum steht. Entsprechend ist ein Quader ein geometrisches Objekt und erbt somit  von der Klasse "geometrisches Objekt". Ein Würfel wiederum ist ein Spezialfall eines Quaders und erbt daher von der Klasse "Quader". Damit ist ein Würfel auch automatisch ein geometrisches Objekt.
 +
 
 +
<source lang="java">
 +
 
 +
public class GeometricObject {
 +
    //...
 +
}
 +
 
 +
public class Cuboid extends GeometricObject{
 +
    //...
 +
}
 +
 
 +
public class Cube extends Cuboid {
 +
    //...
 +
}
 +
 
 +
</source>
  
 
= Eigenschaften =
 
= Eigenschaften =
  
Eine Variable vom Typ einer Superklasse kann ein Objekt einer Unterklasse halten. Entsprechend sind Zuweisungen dieser Form ebenso möglich, da ein Objekt einer Unterklasse ebenso ein Objekt der Oberklasse ist. Dies ist die oben erwähnte ''ist ein'' Beziehung. Eine Variable vom Typ einer Unterklasse kann jedoch keine Objekte der Oberklasse halten und Zuweisungen, die ein Objekt der Oberklasse einer Variablen vom Typ der Unterklasse zuweisen, sind nicht erlaubt.
+
Eine [[Variable]] vom Typ einer Ober- (oder auch Super-)klasse kann ein Objekt einer Unterklasse halten, da ein Objekt einer Unterklasse genauso ein Objekt der zugehörigen Oberklasse ist. Dies ist die oben erwähnte "'''ist ein'''"-Beziehung.  
 +
 
 +
Eine Variable vom Typ einer Unterklasse kann jedoch keine Objekte der Oberklasse halten. Zuweisungen, die ein Objekt der Oberklasse einer Variablen vom Typ einer Unterklasse zuweisen, sind nicht erlaubt.
  
 
= Abstrakte Klassen =
 
= Abstrakte Klassen =
  
Eine Klasse kann sich mit dem Schlüsselwort '''abstract''' als abstrakt deklarieren. Eine abstrakte Klasse deklariert sich damit als ''unvollständig'', d.h. die Implementierung einzelner Methoden ist nicht spezifiziert. Stattdessen wird nur die Signatur der Methode zusammen mit dem Schlüsselwort '''abstract''' angegeben und mit einem einfachen Semikolon abgeschlossen. Dies soll einem Programmierer signalisieren, dass diese Methode von einer erbenden Klasse überschrieben werden ''muss'' und die Implementierung von erbender Klasse zu erbender Klasse unterschiedlich seien ''soll''.
+
==Erläuterung==
 +
 
 +
Eine '''Klasse''' kann mit dem [[Modifikator]] '''abstract''' als abstrakt deklarieren werden. Eine abstrakte Klasse deklariert sich damit als ''unvollständig'', d.h. die Implementierung einzelner Methoden ist nicht spezifiziert. Stattdessen wird nur die [[Signatur]] der Methode zusammen mit dem Schlüsselwort '''abstract''' angegeben und mit einem einfachen Semikolon abgeschlossen. Dies soll einem Programmierer signalisieren, dass diese Methode von einer erbenden Klasse überschrieben werden ''muss'' und die Implementierung von erbender Klasse zu erbender Klasse unterschiedlich sein ''soll''.
  
Entsprechend der ''unvollständigkeit'' einer abstrakten Klasse können keine "reinen" Objekte dieser Klasse instanziiert werden. Eine Variable kann zwar den Typ einer abstrakten Klasse besitzten, da jedoch keine Instanz dieser Klasse existieren kann, muss dieser Variablen ein Objekt einer von dieser Klasse erbenden Klasse zugewiesen werden.
+
Aufgrund dieser ''Unvollständigkeit'' einer abstrakten Klasse können keine "reinen" Objekte dieser Klasse instanziiert werden. Eine Variable kann zwar den Typ einer abstrakten Klasse besitzen, da jedoch keine Instanz dieser Klasse existieren kann, muss dieser Variablen ein Objekt einer von dieser Klasse erbenden Klasse zugewiesen werden.
  
Abstrakte Methoden können nur in einer abstrakten Klasse deklariert werden. Eine abstrakte Klasse muss jedoch keine abstrakten Methoden deklarieren.
+
'''Abstrakte Methoden''' können nur in einer abstrakten Klasse deklariert werden. Eine abstrakte Klasse muss jedoch keine abstrakten Methoden deklarieren.
  
Beim überschreiben einer abstrakten Methode wird in der Signatur das Schlüsselwort '''abstract''' weggelasen.
+
Beim Überschreiben einer abstrakten Methode wird in der Signatur das Schlüsselwort '''abstract''' weggelassen.
  
 
== Beispiele ==
 
== Beispiele ==
Zeile 35: Zeile 61:
 
<source lang="java">
 
<source lang="java">
 
public abstract AbstractClass {
 
public abstract AbstractClass {
     /* Diese Methode muss von einer erbenden Klasse implementiert werden */
+
     /* Diese Methode muss von einer erbenden Klasse implementiert werden. */
 
     public abstract int calculateSomething(int value);
 
     public abstract int calculateSomething(int value);
 
}
 
}
 
</source>
 
</source>
 
<source lang="java">
 
<source lang="java">
public abstract ExtendingClass {
+
public abstract ExtendingClass extends AbstractClass {
     /* Überschreibe die abstrakte Methode mit eigener Implementierung */
+
     /* Überschreibe die abstrakte Methode mit eigener Implementierung. */
 
     public int calculateSomething(int value){
 
     public int calculateSomething(int value){
 
         return value + 5;
 
         return value + 5;
Zeile 52: Zeile 78:
 
public static void main(String[] args){
 
public static void main(String[] args){
 
     AbstractClass object = new ExtendingClass();
 
     AbstractClass object = new ExtendingClass();
     int a = object.calculateSomething(2); //Die ausgeführte Methode wird von der erbenden Klasse implementiert
+
     int a = object.calculateSomething(2); //Die ausgeführte Methode wird von der erbenden Klasse implementiert.
 
     [...]
 
     [...]
 
}
 
}
 
[...]
 
[...]
 
</source>
 
</source>

Aktuelle Version vom 30. November 2016, 16:01 Uhr

Unter Vererbung bezeichnet man das Konzept, zwischen verschiedenen Klassen eine "ist ein"-Beziehung herzustellen. Hauptsächlich wird Vererbung verwendet, um Zeit zu sparen und Code einfacher zu gestalten, wenn mehrere Klassen sehr ähnliche Funktionalitäten bereitstellen sollen. Das Erben von mehr als einer Klasse ist in Java nicht möglich. Eine erbende Klasse wird auch Unterklasse oder Subclass, die vererbte Klasse entsprechend Oberklasse oder Superclass genannt.

Deklaration

Die Vererbung wird in der erbenden Klasse durch das Schlüsselwort extends (engl. erweitert) deklariert, gefolgt vom Namen der vererbenden Oberklasse.

public class Subclass extends Superclass{...}

Verwendung

Erläuterung

Eine erbende Klasse besitzt alle Attribute und Methoden der Oberklasse. Die erbende Klasse kann zwar direkt aufrufen, hat aber, wie jede andere Klasse auch, keinen direkten Zugriff auf die privaten Methoden oder Attribute der Oberklasse. Sie kann jedoch auf beschützte Attribute und Objekte zugreifen.

Erbende Klassen können zudem Methoden der Oberklasse überschreiben. Dabei wird einfach die gesamte Signatur der zu überschreibenden Methode bei der Deklaration der überschreibenden Methode übernommen.

All dies wird getan, um in Sammlungen von Objekten einer Oberklasse verschiedene Objekte unterschiedlicher Unterklassen zu sammeln und das Verhalten verschiedener Methodenaufrufe von den Unterklassen abhängig zu machen, ohne sich jedoch selbst um die entsprechende Implementierung kümmern zu müssen.

Implizit erbt jede Klasse in Java automatisch von der Klasse Object. Die Methoden dieser Klasse sind jedoch selten wirklich hilfreich implementiert. So vergleicht .equals(...) nur die Referenzen der übergebenen Objekte miteinander, nicht aber deren Inhalt. .toString() gibt nur einen pseudo-zufällig generierten String zurück, der das Objekt identifizieren kann, jedoch keinerlei hilfreiche Informationen enthält. Entsprechend sollten diese Methoden bei Bedarf überschrieben werden.

Beispiel

Ein geometrisches Objekt beschreibt etwas, das in einem Raum steht. Entsprechend ist ein Quader ein geometrisches Objekt und erbt somit von der Klasse "geometrisches Objekt". Ein Würfel wiederum ist ein Spezialfall eines Quaders und erbt daher von der Klasse "Quader". Damit ist ein Würfel auch automatisch ein geometrisches Objekt.


public class GeometricObject {
    //...
}

public class Cuboid extends GeometricObject{
    //...
}

public class Cube extends Cuboid {
    //...
}

Eigenschaften

Eine Variable vom Typ einer Ober- (oder auch Super-)klasse kann ein Objekt einer Unterklasse halten, da ein Objekt einer Unterklasse genauso ein Objekt der zugehörigen Oberklasse ist. Dies ist die oben erwähnte "ist ein"-Beziehung.

Eine Variable vom Typ einer Unterklasse kann jedoch keine Objekte der Oberklasse halten. Zuweisungen, die ein Objekt der Oberklasse einer Variablen vom Typ einer Unterklasse zuweisen, sind nicht erlaubt.

Abstrakte Klassen

Erläuterung

Eine Klasse kann mit dem Modifikator abstract als abstrakt deklarieren werden. Eine abstrakte Klasse deklariert sich damit als unvollständig, d.h. die Implementierung einzelner Methoden ist nicht spezifiziert. Stattdessen wird nur die Signatur der Methode zusammen mit dem Schlüsselwort abstract angegeben und mit einem einfachen Semikolon abgeschlossen. Dies soll einem Programmierer signalisieren, dass diese Methode von einer erbenden Klasse überschrieben werden muss und die Implementierung von erbender Klasse zu erbender Klasse unterschiedlich sein soll.

Aufgrund dieser Unvollständigkeit einer abstrakten Klasse können keine "reinen" Objekte dieser Klasse instanziiert werden. Eine Variable kann zwar den Typ einer abstrakten Klasse besitzen, da jedoch keine Instanz dieser Klasse existieren kann, muss dieser Variablen ein Objekt einer von dieser Klasse erbenden Klasse zugewiesen werden.

Abstrakte Methoden können nur in einer abstrakten Klasse deklariert werden. Eine abstrakte Klasse muss jedoch keine abstrakten Methoden deklarieren.

Beim Überschreiben einer abstrakten Methode wird in der Signatur das Schlüsselwort abstract weggelassen.

Beispiele

public abstract AbstractClass {
    /* Diese Methode muss von einer erbenden Klasse implementiert werden. */
    public abstract int calculateSomething(int value);
}
public abstract ExtendingClass extends AbstractClass {
    /* Überschreibe die abstrakte Methode mit eigener Implementierung. */
    public int calculateSomething(int value){
        return value + 5;
    }
}
[...]
public static void main(String[] args){
    AbstractClass object = new ExtendingClass();
    int a = object.calculateSomething(2); //Die ausgeführte Methode wird von der erbenden Klasse implementiert.
    [...]
}
[...]