SemaTrain Logo Ein Fachportal von SemaTrain

Vererbung (Basics): extends, super, override

Sie verstehen Vererbung in Java: Gemeinsamkeiten in eine Basisklasse ziehen und Spezialisierungen per extends sauber modellieren – kursnah im SemaTrain-Kontext.

Hinweis: Beispiele nutzen Beispieldaten (didaktisch, nicht verbindlich).

Java Grundlagen Schulung – Kursbezug

Dieses Kapitel ist Teil des Lernpfads zur Java Grundlagen Schulung. Termine & Buchung laufen über SemaTrain.de.

Hinweis: Beispiele sind kursnah, aber mit Beispieldaten.

Ziel dieses Kapitels: Sie können Gemeinsamkeiten in eine Basisklasse ziehen (extends), Methoden sinnvoll überschreiben (override) und mit super Basisklassenlogik wiederverwenden.

Worum geht’s?

Lehr-Lernziele

Nach diesem Kapitel können Sie …

Wie Ziele erreicht werden: Beispiele zeigen „Basisklasse Kurs“ + Spezialisierungen (LZ2), Quiz prüft is-a/override/super (LZ1–LZ4), Mini-Projekt baut zwei Kurs-Typen mit überschriebenen Regeln/Ausgaben (LZ2–LZ4).

is-a vs. hat-a

is-a (Vererbung passt)

  • OnlineKurs ist ein Kursclass OnlineKurs extends Kurs
  • PraesenzKurs ist ein Kursextends

hat-a (Komposition passt besser)

  • Kurs hat einen Trainer → Feld Trainer trainer; (keine Vererbung)
  • Kurs hat einen Ort → Feld String ort; (kein „Ort extends Kurs“)

Basisklasse + Spezialisierung (extends)

Wir modellieren „Kurs“ als Basis – Online/Präsenz als Spezialisierung (kursnah, mit Beispielwerten).

Beispiel: extends + @Override + super (LZ2–LZ4) (Java)
// Basisklasse
class Kurs {
  protected String name;
  protected int dauerTage;
  protected double preis; // Beispielwert

  Kurs(String name, int dauerTage, double preis) {
    this.name = name;
    this.dauerTage = dauerTage;
    this.preis = preis;
  }

  // Basisausgabe
  public void druckeInfo() {
    System.out.println(name + " | " + dauerTage + " Tage | Preis (Beispiel): " + preis + " €");
  }

  // Basiregel (kann überschrieben werden)
  public double endpreis() {
    return preis; // Standard: kein Rabatt
  }
}

// Spezialisierung: Online
class OnlineKurs extends Kurs {
  OnlineKurs(String name, int dauerTage, double preis) {
    super(name, dauerTage, preis); // Konstruktor der Basisklasse
  }

  @Override
  public double endpreis() {
    // Beispielregel: Online & Dauer >= 3 => 10%
    boolean rabatt = dauerTage >= 3;
    return preis * (rabatt ? 0.90 : 1.0);
  }

  @Override
  public void druckeInfo() {
    super.druckeInfo(); // Basisteil
    System.out.println("Format: Online | Ort: remote");
  }
}

// Spezialisierung: Präsenz
class PraesenzKurs extends Kurs {
  private String ort;

  PraesenzKurs(String name, int dauerTage, double preis, String ort) {
    super(name, dauerTage, preis);
    this.ort = ort;
  }

  @Override
  public void druckeInfo() {
    super.druckeInfo();
    System.out.println("Format: Praesenz | Ort: " + ort);
  }
}

public class VererbungDemo {
  public static void main(String[] args) {
    Kurs k1 = new OnlineKurs("Java Grundlagen Schulung", 3, 1490.00);
    Kurs k2 = new PraesenzKurs("Java Grundlagen Schulung", 3, 1490.00, "Hamburg");

    k1.druckeInfo();
    System.out.println("Endpreis (Beispiel): " + k1.endpreis() + " €");
    System.out.println("---");
    k2.druckeInfo();
    System.out.println("Endpreis (Beispiel): " + k2.endpreis() + " €");
  }
}

Polymorphie: gleiche Schnittstelle, anderes Verhalten

Der Clou: Variable vom Typ Kurs kann auf OnlineKurs oder PraesenzKurs zeigen. Beim Aufruf von endpreis() / druckeInfo() gilt die überschriebene Version der Kindklasse.

Beispiel: Polymorphie in einer Schleife (LZ3) (Java)
public class PolymorphieKurz {
  public static void main(String[] args) {
    Kurs[] kurse = new Kurs[] {
      new OnlineKurs("Java Grundlagen Schulung", 3, 1490.00),
      new PraesenzKurs("Java Grundlagen Schulung", 2, 990.00, "Hamburg")
    };

    for (Kurs k : kurse) {
      k.druckeInfo();
      System.out.println("Endpreis (Beispiel): " + k.endpreis() + " €");
      System.out.println("---");
    }
  }
}

Praxisaufgabe (Mini)

Sie bauen eine Basisklasse und zwei Spezialisierungen – inklusive überschriebenem Verhalten.

Beitrag zu den Lehr-Lernzielen: LZ2 (extends), LZ3 (override), LZ4 (super), plus Entscheidungsregel LZ1 (is-a vs. hat-a) beim Modellieren.

  1. Basisklasse Kurs: Felder name, dauerTage, preis; Methode druckeInfo() und endpreis().
  2. Kindklasse OnlineKurs: überschreibt endpreis() (Beispiel: 10% bei Dauer ≥ 3) und ergänzt Ausgabe.
  3. Kindklasse PraesenzKurs: hat zusätzlich ort und ergänzt Ausgabe.
  4. Test: Array vom Typ Kurs[] anlegen und alle Kurse per Schleife ausgeben.
Lösung anzeigen
Lösung: Vererbung + Polymorphie (Beispielwerte) (Java)
class Kurs {
  protected String name;
  protected int dauerTage;
  protected double preis;

  Kurs(String name, int dauerTage, double preis) {
    this.name = name;
    this.dauerTage = dauerTage;
    this.preis = preis;
  }

  public void druckeInfo() {
    System.out.println("Kurs: " + name + " | Dauer: " + dauerTage + " Tage");
  }

  public double endpreis() {
    return preis;
  }
}

class OnlineKurs extends Kurs {
  OnlineKurs(String name, int dauerTage, double preis) {
    super(name, dauerTage, preis);
  }

  @Override
  public double endpreis() {
    return preis * (dauerTage >= 3 ? 0.90 : 1.0); // 10% Beispiel
  }

  @Override
  public void druckeInfo() {
    super.druckeInfo();
    System.out.println("Format: Online | Ort: remote");
    System.out.println("Preis (Beispiel): " + endpreis() + " €");
  }
}

class PraesenzKurs extends Kurs {
  private String ort;

  PraesenzKurs(String name, int dauerTage, double preis, String ort) {
    super(name, dauerTage, preis);
    this.ort = ort;
  }

  @Override
  public void druckeInfo() {
    super.druckeInfo();
    System.out.println("Format: Praesenz | Ort: " + ort);
    System.out.println("Preis (Beispiel): " + endpreis() + " €");
  }
}

public class MiniProjektVererbung {
  public static void main(String[] args) {
    Kurs[] kurse = new Kurs[] {
      new OnlineKurs("Java Grundlagen Schulung", 3, 1490.00),
      new PraesenzKurs("Java Grundlagen Schulung", 3, 1490.00, "Hamburg")
    };

    for (Kurs k : kurse) {
      k.druckeInfo();
      System.out.println("---");
    }
  }
}
Optional: typische Stolperfallen
  • Falsches Modell: Vererbung nur bei is-a (nicht bei „hat-a“).
  • @Override vergessen: hilft, Tippfehler zu erkennen (Compiler warnt sonst nicht immer sinnvoll).
  • super(...) nicht aufgerufen: in Kindkonstruktoren muss Basiskonstruktor passen.
  • private Felder in Basis: Unterklassen kommen nicht ran – ggf. protected oder Getter.

Kurz-Takeaways

Quiz: Vererbung (Basics)

1. Wann ist Vererbung (extends) typischerweise sinnvoll? (LZ1)

2. Was macht @Override? (LZ3)

3. Wofür nutzt man super(...) im Konstruktor? (LZ4)

4. Was bedeutet Polymorphie in diesem Kontext? (LZ3)

Praxisaufgabe

Mini-Projekt: Kurs-Typen mit Regeln (Online vs. Präsenz)

Sie modellieren Kurs-Typen als Vererbungshierarchie und kapseln Unterschiede in überschriebenen Methoden.

Beitrag zu den Lehr-Lernzielen:
LZ2 (Basisklasse + extends), LZ3 (override), LZ4 (super), plus LZ1 (is-a) bei der Modellentscheidung.

Aufgabe

Lösung anzeigen
Lösung: Vererbung + Polymorphie (mit abstract, optional) (Java)
abstract class Kurs {
  protected String name;
  protected int dauerTage;
  protected double preis;

  Kurs(String name, int dauerTage, double preis) {
    this.name = name;
    this.dauerTage = dauerTage;
    this.preis = preis;
  }

  public abstract String formatText();

  public double endpreis() {
    return preis;
  }

  public void druckeInfo() {
    System.out.println("Kurs: " + name + " | " + formatText() + " | " + dauerTage + " Tage");
    System.out.println("Endpreis (Beispiel): " + endpreis() + " €");
  }
}

class OnlineKurs extends Kurs {
  OnlineKurs(String name, int dauerTage, double preis) {
    super(name, dauerTage, preis);
  }

  @Override
  public String formatText() {
    return "Online (remote)";
  }

  @Override
  public double endpreis() {
    return preis * (dauerTage >= 3 ? 0.90 : 1.0); // 10% Beispiel
  }
}

class PraesenzKurs extends Kurs {
  private String ort;

  PraesenzKurs(String name, int dauerTage, double preis, String ort) {
    super(name, dauerTage, preis);
    this.ort = ort;
  }

  @Override
  public String formatText() {
    return "Praesenz (" + ort + ")";
  }
}

public class KursTypenProjekt {
  public static void main(String[] args) {
    Kurs[] kurse = new Kurs[] {
      new OnlineKurs("Java Grundlagen Schulung", 3, 1490.00),
      new PraesenzKurs("Java Grundlagen Schulung", 2, 990.00, "Hamburg")
    };

    for (Kurs k : kurse) {
      k.druckeInfo();
      System.out.println("---");
    }
  }
}