04_Inheritance
Code-Dateien
| Dateiname | Aktion |
|---|---|
| CODECode_Fahrzeug.zip | Download |
| CODECode_Fenster.zip | Download |
| CODECode_Mitarbeiter.zip | Download |
| CODECode_Mitarbeiter_Teil1.zip | Download |
| CODECode_Mitarbeiter_Teil2.zip | Download |
| CODECode_Student.zip | Download |
Videos
| Dateiname | Aktion |
|---|---|
| VIDEOVideo_Bauernhof_D | Abspielen |
| VIDEOVideo_Fahrzeug_Teil1_D | Abspielen |
| VIDEOVideo_Fenster_D | Abspielen |
| VIDEOVideo_Mitarbeiter_Teil1_D | Abspielen |
| VIDEOVideo_Mitarbeiter_Teil2_D | Abspielen |
| VIDEOVideo_Student_D | Abspielen |
Lernmaterialien
Vererbung Inheritance
Ohne Vererbung
public class Fenster {
private String material;
private double preis;
private boolean kippbar;
private Haus haus;
public Fenster(String material, double preis, boolean kippbar) {
setMaterial(material);
setPreis(preis);
setKippbar(kippbar);
}
public String getMaterial() {
return material;
}
public void setMaterial(String material) {
if ((material.equals("Alu") || material.equals("Holz") || material.equals("Kunststoff"))
this.material = material;
else {
System.out.println("Fehler: ungültiges Material!");
this.material = "Alu";
}
}public class Dachfenster {
private String material;
private double preis;
private boolean kippbar;
private Haus haus;
private boolean sonnenrollo;
public Dachfenster(String material, double preis, boolean kippbar, boolean sonnenrollo) {
setMaterial(material);
setPreis(preis);
setKippbar(kippbar);
setSonnenrollo(sonnenrollo);
}
public String getMaterial() {
return material;
}
public void setMaterial(String material) {
if ((material.equals("Alu") || material.equals("Holz") || material.equals("Kunststoff"))
this.material = material;
else {
System.out.println("Fehler: ungültiges Material!");
this.material = "Alu";
}
}Ohne Vererbung musst man aus der Fenster Klasse alles
noch einmal implemntieren in der Dachfenster Klasse.
Doppelte Implementierung:
Attribute
Konstruktor
Getter/Setter
toString()
Der Vorteil von Vererbung ist:
gemeinsamer Code wird nicht doppelt geschrieben, gewartet und
getestet.
Mit Vererbung
Die Klasse Fenster ist die
Basisklasse
public class Fenster {
...
}Diese Klasse beschreibt allgemeine Eigenschaften, die jedes Fenster hat:
materialpreiskippbarhaus
und allgemeine Methoden wie:
getMaterial()setMaterial()getPreis()setPreis()toString()
Das ist also eine gute Vaterklasse oder Basisklasse.
Was bedeutet Vererbung hier?
Vererbung bedeutet:
Man erstellt eine neue Klasse, die auf Fenster aufbaut
und alles von Fenster übernimmt.
Zum Beispiel:
Dachfensterist auch einFensterPanoramafensterist auch einFensterKellerfensterist auch einFenster
Diese speziellen Fenster sind auch Fenster, haben aber vielleicht noch zusätzliche Eigenschaften.
Vererbung Dachfenster
public class Dachfenster extends Fenster {
private boolean sonnenrollo;
public Dachfenster(String material, double preis, boolean kippbar, boolean sonnenrollo) {
super(material, preis, kippbar);
setSonnenrollo (sonnenrollo);
}
public boolean isSonnenrollo() {
return sonnenrollo;
}
public void setSonnenrollo(boolean sonnenrollo) {
this.sonnenrollo = sonnenrollo;
}
}Was passiert hier genau?
extends Fenster
public class Dachfenster extends FensterDas heißt:
Dachfenster erbt von
Fenster.
Die Klasse Dachfenster bekommt dadurch automatisch
(Geschenk):
Fenster(...)getMaterial()setMaterial()getPreis()setPreis()isKippbar()setKippbar()getHaus()setHaus()toString()(zunächst einmal)
Also alle Methoden der Vaterklasse.
Auch die Eigenschaften werden von der Vaterklasse vererbt.
Warum kann man nicht direkt auf material oder
preis zugreifen?
In deiner Basisklasse sind die Attribute:
private String material;
private double preis;
private boolean kippbar;
private Haus haus;Sie sind also private.
Das bedeutet: Eine Unterklasse wie Dachfenster
erbt zwar das Objektverhalten, darf aber auf diese
Eigenschaften nicht direkt zugreifen.
Also nicht so:
material = "Holz"; // Fehler!
preis = 300; // Fehler!Sondern über die geerbten Setter und Getter:
setMaterial("Holz");
double p = getPreis();
super(...)
In deiner Klasse Fenster gibt es diesen Konstruktor:
public Fenster(String material, double preis, boolean kippbar) {
setMaterial(material);
setPreis(preis);
setKippbar(kippbar);
}Wenn Dachfenster von Fenster erbt, dann
müssen diese geerbten Eigenschaften auch initialisiert werden.
Der Aufruf des Konstruktors der Vaterklasse erfolgt über:
super(material, preis, kippbar);Das ruft den Konstruktor der Oberklasse Fenster auf.
public class Dachfenster extends Fenster {
private boolean sonnenrollo;
public Dachfenster(String material, double preis, boolean kippbar, boolean sonnenrollo) {
super(material, preis, kippbar);
setSonnenrollo (sonnenrollo);
}
Also:
super(...)legt ein neuesFensteran und verwendet denFensterKonstruktor.setSonnenrollo (sonnenrollo);initialisiert die zusätzlichen Eigenschaften vonDachfenster.
Somit bedeutet super(...)
Vaterklasse.
Test
public class Test {
public static void main(String[] args) {
Dachfenster df = new Dachfenster("Holz", 450.0, true, true);
System.out.println(df.getMaterial());
System.out.println(df.getPreis());
System.out.println(df.isKippbar());
System.out.println(df.isSonnenrollo());
df.setPreis(750);
df.setSonnenrollo(false);
System.out.println(df.toString());
//Es fehlt die Eigenschaft Sonnenrollo
}
}Hier sieht man:
Dachfenster hat eigene Methoden wie:
isSonnenrollo()setSonnenrollo(...)
und geerbte Methoden aus Fenster wie:
getMaterial()getPreis()isKippbar()
Methoden überschreiben
toString()
Eine Unterklasse kann Methoden der Oberklasse anpassen.
Zum Beispiel toString():
public class Fenster {
...
@Override
public String toString() {
if (kippbar)
return "Fenster: " + material + " " + preis + " EUR kippbar";
else
return "Fenster: " + material + " " + preis + " EUR nicht kippbar";
}
}Dachfenster df = new Dachfenster("Alu", 899, false, true);
System.out.println(df);
Ausgabe:
Fenster: Alu 899 EUR nicht kippbarEs fehlt bei Dachfenster die Ausgabe der Eigenschaft
sonnenrollo.
public class Dachfenster {
...
@Override
public String toString() {
if (sonnenrollo == true)
return super.toString() + " mit Sonnenrollo";
else
return super.toString() + " ohne Sonnenrollo";
}Bedeutung:
super.toString()verwendet die Ausgabe ausFensterdanach wird die Zusatzinformation von
Dachfensterergänzt
Dachfenster df = new Dachfenster("Alu", 899, false, true);
System.out.println(df);
Ausgabe:
Fenster: Alu 899 EUR nicht kippbar mit SonnenrollogetPreisInklEinbau()
Der Einbau bei einem “normalen” Fenster kostet 800 Euro.
public class Fenster {
...
public double getPreisInklEinbau() {
return preis + 800;
}Der Einbau bei einem Dachfenster kostet 9000 Euro. Zusätzlich werden für den Einbau der Sonnenrollo 600 Euro verrechnet.
public class Dachfenster extends Fenster {
...
@Override
public double getPreisInklEinbau() {
if (sonnenrollo)
return getPreis() + 9000 + 600;
else
return getPreis() + 9000;
}
}abstract
Ausgehend von der Basisklasse Fenster kann man folgende
Fenster herstellen:
1. Dachfenster
Zusätzliche Eigenschaften:
sonnenrollo : boolean
2. Panoramafenster
Zusätzliche Eigenschaften:
breite : doublehoehe : doubledreifachverglasung : boolean
3. Kellerfenster
Zusätzliche Eigenschaften:
einbruchsicher : booleanlichtschacht : boolean
4. Schiebefenster
Zusätzliche Eigenschaften:
anzahlFluegel : intschieneAusAluminium : boolean
5. Rundfenster
Zusätzliche Eigenschaften:
radius : doublefestverglast : boolean
6. Sicherheitsfenster
Zusätzliche Eigenschaften:
sicherheitsstufe : intpanzerglas : boolean
7. Schallschutzfenster
Zusätzliche Eigenschaften:
schallschutzklasse : intdezibelReduktion : double
8. Energiesparfenster
Zusätzliche Eigenschaften:
uWert : doubledreifachverglasung : booleanwaermeschutzbeschichtung : boolean
9. Balkonfenster
Zusätzliche Eigenschaften:
tuergriffMitSchloss : booleanbodentief : boolean
10. SmartFenster
Zusätzliche Eigenschaften:
elektrischSteuerbar : booleanregensensor : booleanverdunkelbar : boolean
11. NormalesFenster
Keine zusätzlichen Eigenschaften.
Somit gibt es eigentlich kein Fenster sondern nur die oben genannten!
Eine abstract class ist eine unvollständige
Klasse, von der keine Instanz (new Fenster(...))
erstellt werden kann.
Sie dient als gemeinsame Oberklasse für andere Klassen, aber von ihr selbst können keine Objekte erzeugt werden.
Das heißt:
Fenster f = new Fenster(...);wäre nicht erlaubt, wenn Fenster als
abstract definiert ist.
Man verwendet eine abstrakte Klasse, wenn man sagen möchte:
Es gibt gemeinsame Eigenschaften und Methoden für alle Unterklassen.
Aber die Oberklasse selbst ist eher ein allgemeines Konzept.
Nur konkrete Unterklassen sollen wirklich erzeugt werden.
So würde das aussehen
public abstract class Fenster {
private String material;
private double preis;
private boolean kippbar;
private Haus haus;Der einzige neue Teil ist:
public abstract class FensterJetzt darf man kein Objekt (Instanz) mehr direkt erzeugen:
Fenster f = new Fenster("Holz", 300.0, true); // FehlerAber Unterklassen darf man weiterhin erzeugen:
Dachfenster d = new Dachfenster("Holz", 450.0, true, true);Die eigentlichen konkreten Typen (können Instanzen angelegt werden) sind dann zum Beispiel:
DachfensterKellerfensterSchiebefenster
Abstrakte Klassen können normale Methoden haben.
Abstrakte Methoden
Eine abstrakte Klasse kann zusätzlich abstrakte Methoden enthalten.
Das sind Methoden ohne Implementierung.
Sie geben nur vor, dass jede Unterklasse diese Methode selbst schreiben muss.
Beispiel:
public abstract class Fenster {
private String material;
private double preis;
private boolean kippbar;
public abstract double getPreisInklEinbau();
}Hier ist: getPreisInklEinbau() eine abstrakte
Methode.
Sie hat:
keinen Methodenkörper
nur einen Kopf
ein Semikolon statt
{ }
!!! Unterklasse muss diese Methode dann implementieren !!!
public class Dachfenster extends Fenster {
private boolean sonnenrollo;
@Override
public double getPreisInklEinbau() {
if (sonnenrollo)
return getPreis() + 9000 + 600;
else
return getPreis() + 9000;
}
}Und z. B. noch:
public class Kellerfenster extends Fenster {
private boolean einbruchsicher;
@Override
public double getPreisInklEinbau() {
if (einbruchsicher)
return getPreis() + 300 + 3000;
else
return getPreis() + 300;
}
}Die Oberklasse sagt:
Jede Unterklasse von
Fenstermuss die MethodegetPreisInklEinbau()implementieren.
Dadurch ist eine einheitliche Struktur vorgegeben.