-
Notifications
You must be signed in to change notification settings - Fork 2
Tag 08: OOP Interfaces, Inheritance, Abstraction, Polymorphism
Information Hiding
Attribute einer Klasse als private deklarieren z.B. Getter/Setter. Damit kümmert sich die Klasse um die Ausgabe und Zuweisung der Attribute. Für andere Klassen nicht sichtbar wie die Klasse dies macht.
Interfaces sind Sammlungen von Funktionen (Methoden) die von anderen Klassen implementiert und verwendet werden können. Sie können keine Attribute (Eigenschaften) enthalten. Sie werden häufig zur Vereinheitlichung verwendet.
In IntelliJ Rechtsklick auf den gewünschten Ordner --> New --> Java Class
Dann Interface wählen
Konvention: Namen von Interfaces werden groß geschrieben und sollten auf ...able enden z.B. Feedable
In Interfaces schreibt man lediglich Methoden-Signaturen
z.B. (in Interface Feedable)
public void feed(int amount);
Da in einem Interface automatisch alle Methoden public sind kann dies auch weggelassen werden, also
void feed(int amount);
Durch das Schlüsselwort implements gefolgt von dem Namen des Interfaces. Klassen können beliebig viele Interfaces implementieren.
z.B.
public class Pet implements Feedable {
...
}
Implementiert eine Klasse ein Interface, so muss jede Methode in der Klasse überschrieben werden. Das public Schlüsselwort ist hier zwingend notwendig.
z.B. (in Klasse Pet)
@Override
public void feed(int amount) {
hungry = false;
}
@Override zeigt an, dass die Methode an anderer Stelle definiert wurde.
Man kann auch Variablen vom Typ eines Interface erstellen und ihnen ein Objekt zuweisen, dessen Klasse das Interface implementiert hat.
z.B.
Feedable petOne = new Pet();
Eine Erstellung eines Objektes (Instanz) von einem Interface ist NICHT möglich.
Zu deutsch "Vererbung". Klassen können von anderen Klassen erben. Hierbei werden sowohl Methoden (Funktionen) als auch Attribute (Eigenschaften) vererbt. Auch von der implementierte Interfaces werden vererbt.
Vokabeln:
- Elternklasse / Parent Class / Superclass: Die Klasse die vererbt (s. Abb. Vehicle)
- Kindklasse / Child Class / Subclass: Die Klasse die erbt (bzw. die Superclass erweitert) (s. Abb. Car, Airplane)
Subclasses können nur von einer anderen Superclass erben. Beliebig viele Subclasses können aber von einer Superclass erben.
Eine Kindklasse hat nur eine Elternklasse. Eine Elternklasse hat beliebig viele Kindklassen.
Eine Vererbung in Reihe ist auch möglich. Auch eine Elternklasse darf eine Elternklasse haben.
Vererbung sollte nur dann verwendet werden wenn es logisch Sinn macht, nicht nur um Code zu sparen!
Die Vererbung gibt man in der Subclass an durch das Schlüsselwort extends
z.B.
public class Dog extends Pet {
...
}
Hier erbt die Klasse Dog von der Klasse Pet und übernimmt somit automatisch alle Attribute und Methoden die in der Klasse Petdefiniert wurden. Diese müssen also nicht mehr in der Klasse Dog wiederholt werden.
Man kann allerdings die Klasse Dog um Attribute und Methoden erweitern die speziell auf Hunde zutreffen, nicht aber allgemein auf jede Art von Haustier.
Attribute die mit private in der Superclass deklariert wurden können nicht von der Subclass abgerufen werden. Hier benutzt man das Schlüsselwort protected
Auf den Konstruktor der Superclass kann man durch super() zugreifen. Dies sollte man auch so im Konstruktor der Subclass tun.
z.B.
public Dog(String name, int age, String furColor) {
super(name, age);
this.furColor = furColor;
}
Auch kann man durch super auf Methoden der Superclass zugreifen.
z.B. (in Klasse Dog)
super.makeSound();
Dies führt dann die Methode makeSound() aus, so wie sie in der Klasse Pet definiert ist.
In der Main lässt sich die (Super-)Klasse aufrufen und ein Objekt erstellen. Dieses Objekt beschreibt aber nur die übergeordnete Kategorie; in unserem Beispiel Pet und nicht Dog oder Cat.

Um diesen Konflikt zu verhindern, kann man Klassen abstrahieren.
Dies erfolgt in der ersten Zeile des Codes vor dem Namen der Klasse mit dem Ausdruck abstract.

Eine typische Fehlermeldung, wenn kein Objekt aus der Klasse mehr erstellt werden kann, wäre beispielsweise:
"java: Klasse ist abstrakt und kann nicht instanziert werden"
Ergänzend dazu kann innerhalb der abstrakten Klasse eine abstrakte Methode erstellt werden.
Auch hier wird der Ausdruck abstract verwendet.
Es wird nur die Methodensignatur angelegt!

Auf die abstrakte Methode aus der abstrahierten Klasse (in unserem Beispiel Pet) kann innerhalb der Subklassen (Cat und Dog) zugegriffen werden und ein Rückgabewert erstellt werden.

In der übergeordneten Klasse kann eine Methode erstellt werden, die auf alle Subklassen zutrifft. Die enthaltenen Werte können sich unterscheiden. In unserem Beispiel wird in der Klasse Pet eine Variable erstellt mit:
public String animalSound(){
return "animal Sound";
}
In den Subklassen Cat bzw. Dog kann diese Methode ebenfalls aufgerufen und mit einem Return Wert zurückgegeben werden mit:
public String animalSound(){
return "miau";
}
Im Gesamtkontext stellt es sich wie folgt dar. animalSound ist nun über die Main aufrufbar.
In der Main Klasse kann nun die in den Klassen vorhandenen Methode (hier animalSound) angezeigt werden.

Nachdem die Methode animalSound in Klasse und Subklasse vorhanden ist, kann die Erstellung auch so erfolgen:

Der tatsächliche Rückgabewert der Methode animalSound kommt aus der Klasse, deren Objekt mit dem Befehl new angelegt wurde (hier wuff in der Klasse Dog.
Man spricht von Polymorphie, da in dem Ausdruck zwei verschiedene Klassen stecken.
Ein weiteres Beispiel für Polymorphie ist folgendes, bei dem eine Variable vom Typ List erstellt wird, die eine ArrayList beinhaltet:

Das Keyword static vor einer Variablen (oder Methode/Klasse) besagt, dass diese Variable für alle Objekte gleich gesetzt wird.
Legt man eine static Variable in der übergeordneten Klasse (hier Pet) an, überschreibt diese Variable die Werte in den Unterklassen.

Eine Änderung der static Variablen ist in der Main trotzdem möglich.
Ohne den Zusatz static wird die Eigenschaft für jedes Objekt abgespeichert.
Mit dem Zusatz static wird nur einmal für die ganze Klasse (und Subklasse) abgespeichert.
Wenn das Überschreiben einer static Variable verhindert werden soll, kann dies mit der Konstante final gesetzt werden.
Die Schreibweise des Variablennamen sollte abgeändert werden in GROSSBUCHSTABEN.
Haustiere muss man füttern, sonst sterben sie!
