Von Nova Trent, Junior Entwicklerin bei Java Fleet Systems Consulting

Schwierigkeit: 🟢 Einsteiger
Lesezeit: 35–40 Minuten
Voraussetzungen: Tag 1–8 abgeschlossen


📋 Kursübersicht: Java OOP in 10 Tagen

TagThemaStatus
1OOP-Konzepte & erste Klasse✅ Abgeschlossen
2Attribute & Methoden✅ Abgeschlossen
3Datenkapselung & Sichtbarkeit✅ Abgeschlossen
4Konstruktoren✅ Abgeschlossen
5Konstanten & Static✅ Abgeschlossen 🔴
6Vererbung – Grundlagen✅ Abgeschlossen
7Vererbung – Polymorphie & Abstrakte Klassen✅ Abgeschlossen
8Typumwandlung & instanceof✅ Abgeschlossen
→ 9Interfaces & Enumerationen📍 Du bist hier
10Ausnahmebehandlung🔴 KOPFNUSS

Voraussetzung: Tag 1–8 abgeschlossen


🔄 Kurz-Wiederholung: Challenge von Tag 8

Die Aufgabe war: Erstelle ein Tierheim-System mit Tier, Hund und Katze.

Lösung:

public abstract class Tier {
    protected String name;
    protected int alter;
    
    public Tier(String name, int alter) {
        this.name = name;
        this.alter = alter;
    }
    
    public abstract void lautGeben();
    
    public void info() {
        System.out.println(name + " (" + alter + " Jahre)");
    }
}

public class Hund extends Tier {
    private String rasse;
    
    public Hund(String name, int alter, String rasse) {
        super(name, alter);
        this.rasse = rasse;
    }
    
    @Override
    public void lautGeben() {
        System.out.println("🐕 " + name + ": Wuff!");
    }
    
    public void apportieren() {
        System.out.println("🎾 " + name + " holt den Ball!");
    }
}

public class Katze extends Tier {
    private boolean istFreigaenger;
    
    public Katze(String name, int alter, boolean istFreigaenger) {
        super(name, alter);
        this.istFreigaenger = istFreigaenger;
    }
    
    @Override
    public void lautGeben() {
        System.out.println("🐈 " + name + ": Miau!");
    }
    
    public void klettern() {
        System.out.println("🌳 " + name + " klettert auf den Baum!");
    }
}

Hast du’s? Super! Heute lernst du zwei weitere mächtige Konzepte!


⚡ Das Wichtigste in 30 Sekunden

Problem 1: Du willst, dass verschiedene Klassen die gleichen Methoden haben, aber sie teilen keine Elternklasse.

Lösung: Interfaces! Ein Vertrag, den Klassen erfüllen müssen.

Problem 2: Du brauchst eine feste Menge von Konstanten (z.B. Status-Werte, Wochentage).

Lösung: Enums! Typsichere Aufzählungen.

Heute lernst du:

  • interface — Verträge für Klassen
  • implements — mehrere Interfaces gleichzeitig
  • ✅ Default-Methoden in Interfaces
  • enum — typsichere Konstanten-Sets

Zeit-Investment: 35–40 Minuten


👋 Nova: „Interfaces haben mir die Augen geöffnet!“

Hey! 👋

Nova hier.

Real talk: Als ich Interfaces verstanden habe, hat OOP endlich klick gemacht. Vorher dachte ich, Vererbung ist alles. Aber Interfaces sind oft das bessere Werkzeug!

Ein Auto kann fahren. Ein Fahrrad kann fahren. Ein Roller kann fahren. Aber sie haben keine gemeinsame Elternklasse! Mit einem Fahrbar-Interface können sie trotzdem gleich behandelt werden.

Los geht’s! 🚀


🟢 GRUNDLAGEN: Interfaces

Was ist ein Interface?

Ein Interface ist ein Vertrag. Es sagt: „Wer mich implementiert, MUSS diese Methoden haben.“

public interface Fahrbar {
    void fahren(int km);
    void bremsen();
}

Keine Implementierung! Nur Signaturen. Die Klasse, die das Interface implementiert, schreibt den Code.

Interface implementieren

public class Auto implements Fahrbar {
    private int kilometerstand = 0;
    
    @Override
    public void fahren(int km) {
        kilometerstand += km;
        System.out.println("Auto fährt " + km + " km.");
    }
    
    @Override
    public void bremsen() {
        System.out.println("Auto bremst!");
    }
}

public class Fahrrad implements Fahrbar {
    @Override
    public void fahren(int km) {
        System.out.println("Fahrrad fährt " + km + " km.");
    }
    
    @Override
    public void bremsen() {
        System.out.println("Fahrrad bremst mit Handbremse!");
    }
}

Abbildung 1: Mehrere Klassen implementieren das gleiche Interface — alle können als „Fahrbar“ behandelt werden.

Das Besondere: Mehrere Interfaces!

Mit Vererbung kannst du nur EINE Elternklasse haben. Mit Interfaces beliebig viele!

public class Tesla implements Fahrbar, Elektrisch, Parkbar {
    @Override
    public void fahren(int km) { ... }
    
    @Override
    public void bremsen() { ... }
    
    @Override
    public void laden() { ... }
    
    @Override
    public void parken() { ... }
}

Abbildung 2: Eine Klasse kann beliebig viele Interfaces implementieren!

Polymorphie mit Interfaces

Wie bei Vererbung funktioniert Polymorphie auch mit Interfaces:

List<Fahrbar> fahrzeuge = new ArrayList<>();
fahrzeuge.add(new Auto());
fahrzeuge.add(new Fahrrad());
fahrzeuge.add(new Roller());

for (Fahrbar f : fahrzeuge) {
    f.fahren(10);  // Jedes Fahrzeug fährt auf seine Weise
}

Interface vs. Abstrakte Klasse

InterfaceAbstrakte Klasse
Mehrfachimplementierung✅ Ja❌ Nein
AttributeNur static finalBeliebig
Konstruktor❌ Nein✅ Ja
Methoden mit CodeNur default/staticJa
Verwendung„kann X“ (Fähigkeit)„ist ein X“ (Identität)

Faustregel:

  • Interface = „Das Objekt kann X“ (Fahrbar, Vergleichbar, Serialisierbar)
  • Abstrakte Klasse = „Das Objekt ist ein X“ (Fahrzeug, Tier, Person)

Default-Methoden (Java 8+)

Interfaces können Methoden mit Implementierung haben:

public interface Fahrbar {
    void fahren(int km);
    void bremsen();
    
    // Default-Methode: Hat eine Standard-Implementierung
    default void hupen() {
        System.out.println("Standard-Hupe: TÖÖT!");
    }
}

// Auto muss hupen() nicht überschreiben (kann aber)
public class Auto implements Fahrbar {
    @Override
    public void fahren(int km) { ... }
    
    @Override
    public void bremsen() { ... }
    
    // hupen() wird geerbt!
}

Statische Methoden in Interfaces

public interface MathOperations {
    static int addiere(int a, int b) {
        return a + b;
    }
}

// Aufruf:
int summe = MathOperations.addiere(5, 3);

Funktionale Interfaces

Ein Interface mit genau einer abstrakten Methode ist ein funktionales Interface — perfekt für Lambdas!

@FunctionalInterface
public interface Berechnung {
    int berechne(int a, int b);
}

// Lambda statt Klasse:
Berechnung addition = (a, b) -> a + b;
Berechnung multiplikation = (a, b) -> a * b;

System.out.println(addition.berechne(5, 3));       // 8
System.out.println(multiplikation.berechne(5, 3)); // 15

🟢 GRUNDLAGEN: Enumerationen

Das Problem mit String-Konstanten

String status = "aktiv";
status = "aktive";  // Tippfehler! Kompiliert aber! 😱
status = "banana";  // Totaler Quatsch! Kompiliert auch! 😱

Die Lösung: Enum

public enum Status {
    AKTIV, INAKTIV, GESPERRT, GELOESCHT
}

Status status = Status.AKTIV;
// status = Status.AKTIVE;  // ❌ Compilerfehler!
// status = "banana";       // ❌ Compilerfehler!

Abbildung 3: Enums bieten Typsicherheit — nur definierte Werte sind erlaubt.

Enum in switch

Status status = Status.AKTIV;

switch (status) {
    case AKTIV -> System.out.println("Benutzer ist aktiv");
    case INAKTIV -> System.out.println("Benutzer ist inaktiv");
    case GESPERRT -> System.out.println("Benutzer ist gesperrt");
    case GELOESCHT -> System.out.println("Benutzer wurde gelöscht");
}

Enum mit Attributen

Enums können Attribute und Methoden haben!

public enum Wochentag {
    MONTAG("Mo", true),
    DIENSTAG("Di", true),
    MITTWOCH("Mi", true),
    DONNERSTAG("Do", true),
    FREITAG("Fr", true),
    SAMSTAG("Sa", false),
    SONNTAG("So", false);
    
    private final String kuerzel;
    private final boolean arbeitstag;
    
    // Konstruktor (immer private!)
    Wochentag(String kuerzel, boolean arbeitstag) {
        this.kuerzel = kuerzel;
        this.arbeitstag = arbeitstag;
    }
    
    public String getKuerzel() { return kuerzel; }
    public boolean isArbeitstag() { return arbeitstag; }
}

// Verwendung:
Wochentag heute = Wochentag.MONTAG;
System.out.println(heute.getKuerzel());     // Mo
System.out.println(heute.isArbeitstag());   // true

Enum-Methoden

Jedes Enum hat eingebaute Methoden:

// Alle Werte als Array
Wochentag[] alle = Wochentag.values();

// String zu Enum
Wochentag tag = Wochentag.valueOf("MONTAG");

// Name und Position
System.out.println(tag.name());     // MONTAG
System.out.println(tag.ordinal());  // 0 (Position)

🟡 PROFESSIONALS

Schon OOP-Erfahrung aus C#, C++, PHP? Hier sind die Java-Besonderheiten.

Für C#-Umsteiger

// C# Interface
public interface IFahrbar {  // I-Prefix ist Konvention
    void Fahren(int km);
}
// Java Interface
public interface Fahrbar {  // Kein I-Prefix!
    void fahren(int km);
}

C# Enums sind simpler (nur Zahlen). Java Enums sind vollwertige Klassen!

Für C++-Umsteiger

C++ hat keine echten Interfaces — du nutzt abstrakte Klassen mit rein virtuellen Methoden.

// C++ "Interface"
class Fahrbar {
public:
    virtual void fahren(int km) = 0;  // Pure virtual
};
// Java Interface
public interface Fahrbar {
    void fahren(int km);
}

Bekannte Java-Interfaces

Diese Interfaces begegnen dir ständig:

// Comparisons
class Person implements Comparable<Person> {
    @Override
    public int compareTo(Person other) { ... }
}

// Collections
class MeineListe implements List<String> { ... }
class MeineMap implements Map<String, Integer> { ... }

// Funktionale Interfaces
Runnable task = () -> System.out.println("Running!");
Predicate<String> istLang = s -> s.length() > 5;
Function<String, Integer> laenge = s -> s.length();

🔵 BONUS

Für Wissbegierige: Sealed Interfaces, EnumSet, Strategy-Pattern.

Sealed Interfaces (Java 17+)

public sealed interface Zahlungsmittel 
    permits Kreditkarte, Überweisung, PayPal {
    void bezahlen(double betrag);
}

public final class Kreditkarte implements Zahlungsmittel { ... }
public final class Überweisung implements Zahlungsmittel { ... }
public final class PayPal implements Zahlungsmittel { ... }

EnumSet und EnumMap

Optimierte Collections für Enums:

// Nur bestimmte Werte
EnumSet<Wochentag> wochenende = EnumSet.of(
    Wochentag.SAMSTAG, 
    Wochentag.SONNTAG
);

// Enum als Key
EnumMap<Status, String> meldungen = new EnumMap<>(Status.class);
meldungen.put(Status.AKTIV, "Benutzer ist online");
meldungen.put(Status.GESPERRT, "Zugang verweigert");

Strategy-Pattern mit Interfaces

interface Versandstrategie {
    double berechneKosten(double gewicht);
}

class StandardVersand implements Versandstrategie {
    public double berechneKosten(double gewicht) {
        return gewicht * 1.5;
    }
}

class ExpressVersand implements Versandstrategie {
    public double berechneKosten(double gewicht) {
        return gewicht * 3.0 + 5.0;
    }
}

class Bestellung {
    private Versandstrategie versand;
    
    public void setVersand(Versandstrategie versand) {
        this.versand = versand;
    }
    
    public double getVersandkosten(double gewicht) {
        return versand.berechneKosten(gewicht);
    }
}

💬 Real Talk

Tom fragt, Nova erklärt — Die Fragen, die sich jeder stellt.

Java Fleet Meetingraum, 15:00 Uhr.


Tom: Nova, wann Interface, wann abstrakte Klasse? Ich komm durcheinander!

Nova: Einfache Regel: „Ist ein“ vs. „Kann“. Ein Hund IST ein Tier → abstrakte Klasse. Ein Hund KANN schwimmen → Interface Schwimmfaehig.

Tom: Und wenn beides passt?

Nova: Dann oft beides! class Hund extends Tier implements Schwimmfaehig

Tom: Okay… und Enums? Warum nicht einfach String-Konstanten?

Nova: tippt

static final String AKTIV = "aktiv";
String status = "aktve";  // Tippfehler, kompiliert! 😱

Mit Enum? Compiler-Fehler. Außerdem: Autocomplete, switch-Support, Attribute…

Tom: Verstehe. Aber Enums mit Konstruktor? Das ist weird.

Nova: Ja, am Anfang. Aber stell dir vor: Wochentag.MONTAG.isArbeitstag(). Das geht nur, wenn Enums Methoden haben können. Enums sind quasi Klassen mit festen Instanzen.


✅ Checkpoint: Hast du es verstanden?

Quiz

Frage 1: Was ist der Hauptunterschied zwischen Interface und abstrakter Klasse?

Frage 2: Kann eine Klasse mehrere Interfaces implementieren?

Frage 3: Was ist ein funktionales Interface?

Frage 4: Warum sind Enums besser als String-Konstanten?

Frage 5: Dieser Code:

public interface A {
    default void test() { System.out.println("A"); }
}
public interface B {
    default void test() { System.out.println("B"); }
}
public class C implements A, B { }

Kompiliert das? Warum (nicht)?


Mini-Challenge

Aufgabe: Erstelle ein Zahlungssystem:

  1. Interface Zahlungsmittel:
    • Methode: boolean bezahlen(double betrag)
    • Methode: double getGuthaben()
  2. Klasse Kreditkarte implements Zahlungsmittel:
    • Attribut: kreditlimit
    • bezahlen() prüft Limit
  3. Klasse PayPal implements Zahlungsmittel:
    • Attribut: email, guthaben
    • bezahlen() zieht vom Guthaben ab
  4. Enum Waehrung:
    • Werte: EUR, USD, GBP, CHF
    • Attribut: symbol („€“, „$“, „£“, „CHF“)

Lösung: Findest du am Anfang von Tag 10! 🚀


❓ FAQ — Häufig gestellte Fragen

Frage 1: Kann ein Interface von einem anderen Interface erben?

Ja! Mit extends:

interface Fahrbar { void fahren(); }
interface Schnell extends Fahrbar { void beschleunigen(); }

Frage 2: Was passiert bei Diamond-Problem mit Default-Methoden?

Wenn zwei Interfaces die gleiche Default-Methode haben, muss die Klasse sie überschreiben:

class C implements A, B {
    @Override
    public void test() {
        A.super.test();  // Wähle A's Version
    }
}

Frage 3: Kann ich Enum erweitern?

Nein! Enums sind implizit final. Du kannst aber Interfaces implementieren.


Frage 4: Wann enum vs. static final?

Enum wenn: Feste, zusammengehörige Werte (Wochentage, Status, Farben). Static final wenn: Einzelne Konstanten (MAX_SIZE, PI).


Frage 5: Kann ich null als Enum-Wert haben?

Ja, eine Enum-Variable kann null sein. Aber null ist kein Enum-Wert selbst.


Frage 6: Wie iteriere ich über alle Enum-Werte?

for (Wochentag tag : Wochentag.values()) {
    System.out.println(tag);
}

Frage 7: Bernd meinte, Interfaces seien „übertrieben“ für kleine Projekte. Stimmt das?

schmunzelt Bernd ist ein Fan von YAGNI („You Ain’t Gonna Need It“). Für ein 100-Zeilen-Skript brauchst du keine Interfaces.

Aber sobald Code wächst, zahlen sich Interfaces aus. Sie ermöglichen Austauschbarkeit, Testing mit Mocks, lose Kopplung. In Bernd’s 40 Jahren hat er gesehen, wie „kleine Projekte“ plötzlich groß wurden. 🤷


📚 Quiz-Lösungen

Frage 1: Hauptunterschied Interface vs. abstrakte Klasse?

Antwort:

  • Interface: Eine Klasse kann mehrere implementieren. Enthält nur Methodensignaturen (+ default/static).
  • Abstrakte Klasse: Eine Klasse kann nur von einer erben. Kann Attribute, Konstruktoren, normale Methoden haben.

Frage 2: Mehrere Interfaces implementieren?

Antwort:

Ja! class Tesla implements Fahrbar, Elektrisch, Parkbar


Frage 3: Funktionales Interface?

Antwort:

Ein Interface mit genau EINER abstrakten Methode. Kann mit Lambda-Ausdrücken verwendet werden.

@FunctionalInterface
interface Berechnung {
    int berechne(int a, int b);
}

Frage 4: Warum Enums besser als String-Konstanten?

Antwort:

  • Typsicherheit (nur definierte Werte)
  • Compilerfehler bei Tippfehlern
  • IDE-Autovervollständigung
  • switch-kompatibel
  • Können Attribute und Methoden haben

Frage 5: Kompiliert das?

public class C implements A, B { }

Antwort:

Nein! Compilerfehler: „class C inherits unrelated defaults for test() from types A and B“

Du musst die Methode überschreiben:

public class C implements A, B {
    @Override
    public void test() {
        A.super.test();  // Oder eigene Implementierung
    }
}

🎉 Tag 9 geschafft!

Fast am Ziel! 🚀

Das hast du heute gelernt:

  • ✅ Interfaces definieren und implementieren
  • ✅ Mehrere Interfaces gleichzeitig
  • ✅ Default-Methoden in Interfaces
  • ✅ Enums für typsichere Konstanten
  • ✅ Enums mit Attributen und Methoden

Nur noch Tag 10 — die letzte KOPFNUSS! 💪


🔮 Wie geht’s weiter?

Morgen in Tag 10: Ausnahmebehandlung 🔴 KOPFNUSS

Das letzte große Thema! Du lernst:

  • try-catch-finally — Fehler abfangen
  • Checked vs. Unchecked Exceptions
  • Eigene Exceptions erstellen
  • throws vs. throw

Das ist essentiell für produktionsfähigen Code! 🎯


📦 Downloads

Starter-Projekt für Tag 9:

⬇️ Tag09_Interfaces_Enums.zip — Komplettes Maven-Projekt

Inhalt:

Tag09_Interfaces_Enums/
├── pom.xml
├── README.md
└── src/main/java/
    └── de/javafleet/oop/
        ├── Main.java
        ├── model/
        │   ├── Tier.java           (Lösung Tag 8)
        │   ├── Hund.java
        │   └── Katze.java
        ├── interfaces/
        │   ├── Fahrbar.java
        │   └── Elektrisch.java
        └── enums/
            ├── Status.java
            └── Wochentag.java

Grafiken:


🔧 Troubleshooting

Problem: „is not abstract and does not override abstract method“

error: Auto is not abstract and does not override abstract method bremsen()

Lösung: Du musst ALLE Methoden des Interfaces implementieren!


Problem: „duplicate default methods“

error: class C inherits unrelated defaults for test() from types A and B

Lösung: Überschreibe die Methode in deiner Klasse.


Problem: „enum types may not be instantiated“

error: enum types may not be instantiated

Lösung: Du kannst kein new Status() machen. Nutze die definierten Werte: Status.AKTIV


🔗 Resources & Links

🟢 Für Einsteiger

RessourceBeschreibungSprache
Oracle — InterfacesOffizielle Doku🇬🇧
Oracle — EnumsOffizielle Doku🇬🇧

🟡 Für Fortgeschrittene

RessourceBeschreibungSprache
Baeldung — Default MethodsDeep Dive🇬🇧
Effective Java — Item 20Interfaces vs. Abstract Classes🇬🇧

👋 Bis morgen!

Tag 9 ist geschafft. Interfaces und Enums sind jetzt deine Werkzeuge!

Morgen: Ausnahmebehandlung — die letzte KOPFNUSS des Kurses.

Du schaffst das! 🚀


Nova Trent
Junior Entwicklerin bei Java Fleet Systems Consulting
„Interfaces sind Verträge. Enums sind typsichere Werte. Beides ist Gold wert!“ 💎


Praxis-Challenge

🎯 Smart-Home-System

Schwierigkeit: 🟡 Fortgeschritten
Geschätzte Zeit: 90–120 Minuten
Voraussetzungen: Tag 1–9 abgeschlossen


Szenario

Du entwickelst eine Smart-Home-Steuerung. Verschiedene Geräte (Lampen, Heizungen, Rollläden, TVs) haben unterschiedliche Fähigkeiten: manche kann man nur ein-/ausschalten, manche dimmen, manche haben Timer.

Diese Aufgabe testet alles aus Tag 6–9:

  • Vererbung (extends)
  • Abstrakte Klassen
  • Interfaces (auch mehrere gleichzeitig)
  • Interface-Vererbung
  • Enumerationen
  • Polymorphie

Teil 1: Enum Raum

Erstelle ein Enum für die Räume im Haus:

public enum Raum {
    WOHNZIMMER,
    SCHLAFZIMMER,
    KUECHE,
    BAD,
    FLUR
}

Teil 2: Interfaces

Interface Schaltbar

Grundlegende Fähigkeit: Ein-/Ausschalten.

MethodeBeschreibung
void einschalten()Schaltet das Gerät ein
void ausschalten()Schaltet das Gerät aus
boolean istAn()Gibt zurück, ob das Gerät an ist

Interface Dimmbar extends Schaltbar

Achtung: Interface erbt von Interface! Dimmbar enthält automatisch alle Methoden von Schaltbar.

MethodeBeschreibung
void setHelligkeit(int prozent)Setzt Helligkeit (0–100)
int getHelligkeit()Gibt aktuelle Helligkeit zurück

Interface Programmierbar

Für Geräte mit Timer-Funktion.

MethodeBeschreibung
void setTimer(int minuten)Startet einen Timer
void timerAbbrechen()Bricht den Timer ab
int getVerbleibendeZeit()Gibt verbleibende Zeit zurück (0 wenn kein Timer)

Teil 3: Abstrakte Basisklasse SmartGeraet

ElementDetails
Attributename (String), raum (Raum-Enum), angeschaltet (boolean)
KonstruktorParameter: name, raum. angeschaltet startet mit false
Abstrakte MethodeString getStatus() — muss von jeder Kindklasse implementiert werden
Konkrete MethodeString getStandort() → gibt zurück: "Name im Raum"
GetterFür alle Attribute

Teil 4: Konkrete Geräteklassen

Klasse Lampe

ElementDetails
extendsSmartGeraet
implementsDimmbar
Zusätzliches Attributhelligkeit (int, 0–100)
Konstruktorname, raum. Helligkeit startet bei 0
einschalten()Setzt angeschaltet = true, Helligkeit auf 100
ausschalten()Setzt angeschaltet = false, Helligkeit auf 0
setHelligkeit()Setzt Helligkeit. Wenn > 0, schalte automatisch ein. Wenn 0, schalte aus
getStatus()"Lampe [Name]: AN (XX%)" oder "Lampe [Name]: AUS"

Klasse Heizung

ElementDetails
extendsSmartGeraet
implementsSchaltbar, Programmierbar
Zusätzliche AttributezielTemperatur (int), timerMinuten (int)
Konstruktorname, raum. Temperatur startet bei 20, Timer bei 0
einschalten()Setzt angeschaltet = true
ausschalten()Setzt angeschaltet = false, bricht Timer ab
setTimer()Setzt timerMinuten
timerAbbrechen()Setzt timerMinuten = 0
getVerbleibendeZeit()Gibt timerMinuten zurück
Neue MethodesetTemperatur(int grad) — setzt Zieltemperatur
getStatus()"Heizung [Name]: AN (XX°C, Timer: XX min)" oder "Heizung [Name]: AUS"

Klasse Rollladen

ElementDetails
extendsSmartGeraet
implementsSchaltbar
Zusätzliches Attributposition (int, 0=geschlossen, 100=offen)
Konstruktorname, raum. Position startet bei 0 (geschlossen)
einschalten()Öffnet Rollladen: position = 100, angeschaltet = true
ausschalten()Schließt Rollladen: position = 0, angeschaltet = false
Neue MethodesetPosition(int prozent) — setzt Position (0–100)
getStatus()"Rollladen [Name]: XX% offen"

Klasse SmartTV

Das komplexeste Gerät — implementiert alle Interfaces!

ElementDetails
extendsSmartGeraet
implementsDimmbar, Programmierbar (Dimmbar beinhaltet bereits Schaltbar!)
Zusätzliche Attributehelligkeit (int), timerMinuten (int), aktuellerKanal (int)
Konstruktorname, raum. Helligkeit 0, Timer 0, Kanal 1
einschalten()Setzt angeschaltet = true, Helligkeit auf 80
ausschalten()Setzt angeschaltet = false, Helligkeit auf 0, bricht Timer ab
setHelligkeit()Setzt Helligkeit (für TV = Bildschirmhelligkeit)
setTimer()Sleep-Timer in Minuten
Neue MethodesetKanal(int kanal) — wechselt den Kanal
getStatus()"TV [Name]: AN (Kanal XX, XX%, Timer: XX min)" oder "TV [Name]: AUS"

Teil 5: Verwaltungsklasse SmartHome

Die zentrale Steuerung für alle Geräte.

public class SmartHome {
    private List<SmartGeraet> geraete = new ArrayList<>();
    
    // Gerät hinzufügen
    public void hinzufuegen(SmartGeraet g) { ... }
    
    // Alle schaltbaren Geräte in einem Raum ausschalten
    public void raumAusschalten(Raum raum) { ... }
    
    // Alle dimmbaren Geräte auf bestimmte Helligkeit setzen
    public void alleDimmenAuf(int prozent) { ... }
    
    // Status aller Geräte ausgeben
    public void statusReport() { ... }
    
    // Bonus: Alle Timer abbrechen
    public void alleTimerAbbrechen() { ... }
}

Hinweise zur Implementierung

raumAusschalten(Raum raum):

  • Iteriere über alle Geräte
  • Prüfe ob Gerät im richtigen Raum ist UND Schaltbar implementiert
  • Nutze: if (geraet instanceof Schaltbar schaltbar && geraet.getRaum() == raum)
  • Rufe schaltbar.ausschalten() auf

alleDimmenAuf(int prozent):

  • Prüfe mit instanceof Dimmbar
  • Nur dimmbare Geräte werden beeinflusst

statusReport():

  • Rufe getStatus() für jedes Gerät auf

Test-Code für Main

public class Main {
    public static void main(String[] args) {
        
        SmartHome haus = new SmartHome();
        
        // Geräte erstellen
        Lampe wohnzimmerLampe = new Lampe("Deckenlampe", Raum.WOHNZIMMER);
        Lampe schlafzimmerLampe = new Lampe("Nachttischlampe", Raum.SCHLAFZIMMER);
        Heizung badHeizung = new Heizung("Fußbodenheizung", Raum.BAD);
        Rollladen wohnzimmerRollladen = new Rollladen("Fenster Süd", Raum.WOHNZIMMER);
        SmartTV tv = new SmartTV("Samsung 55", Raum.WOHNZIMMER);
        
        // Zum SmartHome hinzufügen
        haus.hinzufuegen(wohnzimmerLampe);
        haus.hinzufuegen(schlafzimmerLampe);
        haus.hinzufuegen(badHeizung);
        haus.hinzufuegen(wohnzimmerRollladen);
        haus.hinzufuegen(tv);
        
        System.out.println("=== Geräte einschalten ===");
        wohnzimmerLampe.einschalten();
        wohnzimmerLampe.setHelligkeit(75);
        
        schlafzimmerLampe.einschalten();
        schlafzimmerLampe.setHelligkeit(30);
        
        badHeizung.einschalten();
        badHeizung.setTemperatur(24);
        badHeizung.setTimer(30);
        
        wohnzimmerRollladen.einschalten();  // Öffnet
        wohnzimmerRollladen.setPosition(50);  // Halb offen
        
        tv.einschalten();
        tv.setKanal(7);
        tv.setHelligkeit(60);
        tv.setTimer(120);  // Sleep-Timer: 2 Stunden
        
        System.out.println("\n=== Status Report ===");
        haus.statusReport();
        
        System.out.println("\n=== Wohnzimmer ausschalten ===");
        haus.raumAusschalten(Raum.WOHNZIMMER);
        
        System.out.println("\n=== Status nach Wohnzimmer aus ===");
        haus.statusReport();
        
        System.out.println("\n=== Alle dimmbaren auf 25% ===");
        // Erst wieder einschalten für den Test
        wohnzimmerLampe.einschalten();
        tv.einschalten();
        haus.alleDimmenAuf(25);
        
        System.out.println("\n=== Finaler Status ===");
        haus.statusReport();
    }
}

Erwartete Ausgabe (ungefähr)

=== Geräte einschalten ===

=== Status Report ===
Lampe Deckenlampe: AN (75%)
Lampe Nachttischlampe: AN (30%)
Heizung Fußbodenheizung: AN (24°C, Timer: 30 min)
Rollladen Fenster Süd: 50% offen
TV Samsung 55: AN (Kanal 7, 60%, Timer: 120 min)

=== Wohnzimmer ausschalten ===

=== Status nach Wohnzimmer aus ===
Lampe Deckenlampe: AUS
Lampe Nachttischlampe: AN (30%)
Heizung Fußbodenheizung: AN (24°C, Timer: 30 min)
Rollladen Fenster Süd: 0% offen
TV Samsung 55: AUS

=== Alle dimmbaren auf 25% ===

=== Finaler Status ===
Lampe Deckenlampe: AN (25%)
Lampe Nachttischlampe: AN (25%)
Heizung Fußbodenheizung: AN (24°C, Timer: 30 min)
Rollladen Fenster Süd: 0% offen
TV Samsung 55: AN (25%, Timer: 0 min)

Checkliste: Das wird getestet

Vererbung (Tag 6–7)

  • [ ] SmartGeraet als abstrakte Basisklasse
  • [ ] Alle Geräte erben von SmartGeraet
  • [ ] super() Konstruktor-Aufrufe

Abstrakte Klassen (Tag 7)

  • [ ] SmartGeraet ist abstract
  • [ ] getStatus() ist abstrakte Methode
  • [ ] Jede Kindklasse implementiert getStatus()

Interfaces (Tag 9)

  • [ ] Schaltbar, Dimmbar, Programmierbar als Interfaces
  • [ ] Interface-Vererbung: Dimmbar extends Schaltbar
  • [ ] Mehrere Interfaces: implements Schaltbar, Programmierbar
  • [ ] SmartTV implementiert Dimmbar, Programmierbar

Enums (Tag 9)

  • [ ] Raum als Enum
  • [ ] Verwendung in Attributen und Methoden

Polymorphie (Tag 7–8)

  • [ ] instanceof für Interface-Prüfung
  • [ ] Pattern Matching: instanceof Schaltbar s
  • [ ] Heterogene Liste: List<SmartGeraet>

Projektstruktur

Tag09_SmartHome/
├── pom.xml
├── README.md
└── src/main/java/
    └── de/javafleet/oop/
        ├── Main.java
        ├── SmartHome.java
        ├── enums/
        │   └── Raum.java
        ├── interfaces/
        │   ├── Schaltbar.java
        │   ├── Dimmbar.java
        │   └── Programmierbar.java
        └── geraete/
            ├── SmartGeraet.java
            ├── Lampe.java
            ├── Heizung.java
            ├── Rollladen.java
            └── SmartTV.java

Hinweise

  1. Reihenfolge: Enum → Interfaces → SmartGeraet → Konkrete Klassen → SmartHome
  2. Dimmbar erbt Schaltbar: Wer Dimmbar implementiert, muss auch alle Schaltbar-Methoden implementieren
  3. instanceof mit Pattern Matching: if (geraet instanceof Schaltbar s) bindet direkt die Variable
  4. Vergiss @Override nicht bei Interface-Methoden

Bonus-Aufgaben

Wenn du noch Zeit hast:

  1. Szenen: Erstelle eine Methode szeneAbend(), die alle Lampen auf 30% dimmt und alle Rollläden schließt
  2. Energieverbrauch: Füge jedem Gerät einen Stromverbrauch hinzu und berechne den Gesamtverbrauch
  3. Sprachsteuerung: Implementiere eine Methode sprachbefehl(String befehl), die „Licht an im Wohnzimmer“ versteht

Lösung: Findest du in Tag09_SmartHome_Loesung.md


Tags: #Java #OOP #Interface #Enum #Tutorial

© 2025 Java Fleet Systems Consulting | java-developer.online

Autor

  • Ensign Nova Trent

    24 Jahre alt, frisch von der Universität als Junior Entwicklerin bei Java Fleet Systems Consulting. Nova ist brilliant in Algorithmen und Datenstrukturen, aber neu in der praktischen Java-Enterprise-Entwicklung. Sie brennt darauf, ihre ersten echten Projekte zu bauen und entdeckt dabei die Lücke zwischen Uni-Theorie und Entwickler-Realität. Sie liebt Star Treck das ist der Grund warum alle Sie Ensign Nova nennen und arbeitet daraufhin das sie Ihren ersten Knopf am Kragen bekommt.