Skip to content
IRC-Coding IRC-Coding
Klassenbeziehungen Assoziation Aggregation Komposition Vererbung

OOP Klassenbeziehungen: Assoziation, Aggregation, Komposition & Vererbung

OOP Klassenbeziehungen: Assoziation (hat-ein), Aggregation (besteht-aus), Komposition (ist-Teil-von), Vererbung (ist-ein) mit praktischen Beispielen und UML-Notation.

S

schutzgeist

2 min read

OOP Klassenbeziehungen: Assoziation, Aggregation, Komposition & Vererbung

Dieser Beitrag ist eine umfassende Erläuterung der Klassenbeziehungen in der OOP – inklusive Assoziation, Aggregation, Komposition und Vererbung mit praktischen Beispielen.

In a Nutshell

Klassenbeziehungen beschreiben, wie Objekte miteinander interagieren und zusammenarbeiten, um komplexe Systeme zu bilden. Die vier Hauptbeziehungsarten sind Assoziation, Aggregation, Komposition und Vererbung.

Kompakte Fachbeschreibung

Klassenbeziehungen definieren die Art und Weise, wie Klassen und ihre Objekte miteinander verbunden sind. Sie sind fundamental für die Strukturierung objektorientierter Systeme.

Vier Hauptbeziehungsarten:

1. Assoziation (hat-ein)

  • Beschreibung: Zwei Klassen sind miteinander verbunden
  • Lebenszyklus: Unabhängig voneinander
  • Beispiel: Kunde hat Bestellungen
  • UML: Einfache Linie zwischen Klassen

2. Aggregation (besteht-aus)

  • Beschreibung: “hat-ein” Beziehung, Teile können unabhängig existieren
  • Lebenszyklus: Teil kann ohne Ganzes existieren
  • Beispiel: Auto hat Reifen
  • UML: Linie mit leerer Raute am Ganzen

3. Komposition (ist-Teil-von)

  • Beschreibung: “ist-Teil-von” Beziehung, Teile existieren nur mit Ganzen
  • Lebenszyklus: Teil kann nicht ohne Ganzes existieren
  • Beispiel: Auto hat Motor
  • UML: Linie mit gefüllter Raute am Ganzen

4. Vererbung (ist-ein)

  • Beschreibung: “ist-ein” Beziehung, Spezialisierung
  • Lebenszyklus: Unterklasse erbt von Oberklasse
  • Beispiel: PKW ist ein Fahrzeug
  • UML: Linie mit leerem Pfeil zur Oberklasse

Prüfungsrelevante Stichpunkte

  • Assoziation: Einfache Beziehung zwischen Klassen
  • Aggregation: “hat-ein” Beziehung mit unabhängigen Teilen
  • Komposition: “ist-Teil-von” Beziehung mit abhängigen Teilen
  • Vererbung: “ist-ein” Beziehung mit Spezialisierung
  • Multiplizitäten: 1, , 0..1, 1.., 0..*
  • UML-Notation: Verschiedene Pfeile und Raute-Symbole
  • Lebenszyklus: Abhängigkeit der Objekte zueinander
  • IHK-relevant: Wichtig für Softwarearchitektur und -design

Kernkomponenten

  1. Assoziation: Bidirektionale oder unidirektionale Beziehung
  2. Aggregation: Schwache “hat-ein” Beziehung
  3. Komposition: Starke “ist-Teil-von” Beziehung
  4. Vererbung: Spezialisierung und Wiederverwendung
  5. Multiplizität: Anzahl der Beziehungsinstanzen
  6. Rollen: Bezeichnung der Beziehungsrolle
  7. Navigierbarkeit: Richtung der Beziehung
  8. Qualifizierer: Zusatzinformation zur Beziehung

Praxisbeispiele

1. Assoziation (Kunde - Bestellung)

// Bidirektionale Assoziation
public class Kunde {
    private String kundenId;
    private String name;
    private List<Bestellung> bestellungen = new ArrayList<>();
    
    public void addBestellung(Bestellung bestellung) {
        bestellungen.add(bestellung);
        bestellung.setKunde(this); // Rückreferenz
    }
    
    public List<Bestellung> getBestellungen() {
        return new ArrayList<>(bestellungen);
    }
}

public class Bestellung {
    private String bestellId;
    private Date bestelldatum;
    private Kunde kunde; // Rückreferenz zum Kunden
    
    public void setKunde(Kunde kunde) {
        this.kunde = kunde;
    }
    
    public Kunde getKunde() {
        return kunde;
    }
}

// Verwendung
Kunde meier = new Kunde("1", "Meier");
Bestellung b1 = new Bestellung("B001", new Date());
Bestellung b2 = new Bestellung("B002", new Date());

meier.addBestellung(b1);
meier.addBestellung(b2);

2. Aggregation (Auto - Reifen)

// Aggregation: Auto hat Reifen, Reifen können ohne Auto existieren
public class Auto {
    private String modell;
    private List<Reifen> reifen = new ArrayList<>();
    
    public Auto(String modell) {
        this.modell = modell;
    }
    
    public void addReifen(Reifen reifen) {
        if (reifen.size() < 4) {
            this.reifen.add(reifen);
        }
    }
    
    public void removeReifen(Reifen reifen) {
        this.reifen.remove(reifen);
        // Reifen existiert weiter und kann anderem Auto zugewiesen werden
    }
}

public class Reifen {
    private String hersteller;
    private int groesse;
    
    public Reifen(String hersteller, int groesse) {
        this.hersteller = hersteller;
        this.groesse = groesse;
    }
    
    // Reifen kann unabhängig vom Auto existieren
    public void montieren() {
        System.out.println("Reifen wird montiert");
    }
}

// Verwendung
Auto golf = new Auto("Golf");
Reifen michelin1 = new Reifen("Michelin", 195);
Reifen michelin2 = new Reifen("Michelin", 195);

golf.addReifen(michelin1);
golf.addReifen(michelin2);

// Reifen können entfernt und wiederverwendet werden
golf.removeReifen(michelin1);

3. Komposition (Auto - Motor)

// Komposition: Motor existiert nur mit Auto
public class Auto {
    private String modell;
    private Motor motor; // Motor kann nicht ohne Auto existieren
    
    public Auto(String modell, int leistung) {
        this.modell = modell;
        this.motor = new Motor(leistung); // Motor wird intern erstellt
    }
    
    public void starten() {
        motor.starten();
        System.out.println(modell + " wird gestartet");
    }
    
    public void ausschalten() {
        motor.ausschalten();
        System.out.println(modell + " wird ausgeschaltet");
    }
    
    // Motor wird mit Auto zerstört
    protected void finalize() {
        // Motor wird automatisch aufgeräumt
    }
}

public class Motor {
    private int leistung;
    private boolean laeuft;
    
    // Privater Konstruktor - nur Auto kann Motor erstellen
    protected Motor(int leistung) {
        this.leistung = leistung;
        this.laeuft = false;
    }
    
    protected void starten() {
        this.laeuft = true;
        System.out.println("Motor mit " + leistung + " PS wird gestartet");
    }
    
    protected void ausschalten() {
        this.laeuft = false;
        System.out.println("Motor wird ausgeschaltet");
    }
}

// Verwendung
Auto bmw = new Auto("BMW", 200);
bmw.starten(); // Motor wird intern gestartet
bmw.ausschalten();

// Motor kann nicht unabhängig erstellt werden:
// Motor motor = new Motor(150); // Fehler: Konstruktor ist protected

4. Vererbung (Fahrzeug - Auto)

// Oberklasse
public abstract class Fahrzeug {
    protected String marke;
    protected int baujahr;
    protected int aktuelleGeschwindigkeit = 0;
    
    public Fahrzeug(String marke, int baujahr) {
        this.marke = marke;
        this.baujahr = baujahr;
    }
    
    // Gemeinsame Methoden
    public void beschleunigen(int kmh) {
        this.aktuelleGeschwindigkeit += kmh;
        System.out.println(marke + " beschleunigt auf " + aktuelleGeschwindigkeit + " km/h");
    }
    
    public void bremsen(int kmh) {
        if (aktuelleGeschwindigkeit >= kmh) {
            this.aktuelleGeschwindigkeit -= kmh;
            System.out.println(marke + " bremst auf " + aktuelleGeschwindigkeit + " km/h");
        }
    }
    
    // Abstrakte Methode - muss von Unterklassen implementiert werden
    public abstract void hupen();
    
    // Konkrete Methode - kann überschrieben werden
    public void anzeigen() {
        System.out.println("Fahrzeug: " + marke + ", Baujahr: " + baujahr + 
                          ", Geschwindigkeit: " + aktuelleGeschwindigkeit + " km/h");
    }
}

// Unterkasse
public class Auto extends Fahrzeug {
    private int anzahlTueren;
    private boolean klimaanlage;
    
    public Auto(String marke, int baujahr, int anzahlTueren) {
        super(marke, baujahr); // Oberklassen-Konstruktor aufrufen
        this.anzahlTueren = anzahlTueren;
        this.klimaanlage = false;
    }
    
    // Implementierung der abstrakten Methode
    @Override
    public void hupen() {
        System.out.println("Auto hupt: Tut Tut!");
    }
    
    // Zusätzliche Methode nur für Auto
    public void klimaanlageEin() {
        klimaanlage = true;
        System.out.println("Klimaanlage eingeschaltet");
    }
    
    // Überschreiben der Oberklassen-Methode
    @Override
    public void anzeigen() {
        super.anzeigen(); // Oberklassen-Methode aufrufen
        System.out.println("  Typ: Auto, Türen: " + anzahlTueren + 
                          ", Klimaanlage: " + (klimaanlage ? "an" : "aus"));
    }
}

// Weitere Unterklasse
public class Motorrad extends Fahrzeug {
    private boolean hatSeitenwagen;
    
    public Motorrad(String marke, int baujahr, boolean hatSeitenwagen) {
        super(marke, baujahr);
        this.hatSeitenwagen = hatSeitenwagen;
    }
    
    @Override
    public void hupen() {
        System.out.println("Motorrad hupt: Iiih Iiih!");
    }
    
    public void wheelie() {
        System.out.println("Motorrad macht Wheelie!");
    }
    
    @Override
    public void anzeigen() {
        super.anzeigen();
        System.out.println("  Typ: Motorrad, Seitenwagen: " + 
                          (hatSeitenwagen ? "ja" : "nein"));
    }
}

// Verwendung
Fahrzeug golf = new Auto("Volkswagen", 2023, 5);
Fahrzeug harley = new Motorrad("Harley-Davidson", 2022, false);

golf.hupen();      // Auto hupt: Tut Tut!
harley.hupen();   // Motorrad hupt: Iiih Iiih!

golf.beschleunigen(50);
harley.beschleunigen(80);

golf.anzeigen();
harley.anzeigen();

// Downcasting für spezifische Methoden
if (golf instanceof Auto) {
    Auto autoGolf = (Auto) golf;
    autoGolf.klimaanlageEin();
}

if (harley instanceof Motorrad) {
    Motorrad motorradHarley = (Motorrad) harley;
    motorradHarley.wheelie();
}

UML-Notation für Beziehungen

Assoziation

Kunde 1..* --* Bestellung

Aggregation

Auto 1 --* Reifen

Komposition

Auto 1 --* Motor

Vererbung

Fahrzeug <|-- Auto
Fahrzeug <|-- Motorrad

Multiplizitäten

SymbolBedeutungBeispiel
1Genau eins1 Motor
0..1Null oder eins0..1 Führerschein
*Null oder mehr* Reifen
1..*Mindestens eins1..* Türen
2..4Zwischen 2 und 42..4 Räder

Entscheidungshilfe für Beziehungsarten

Wann welche Beziehung?

Assoziation verwenden wenn:

  • Zwei Klassen interagieren, aber keine Abhängigkeit besteht
  • Beziehung ist temporär oder optional
  • Objekte existieren unabhängig voneinander

Aggregation verwenden wenn:

  • “hat-ein” Beziehung vorliegt
  • Teile können ohne Ganzes existieren
  • Teile können zwischen verschiedenen Ganzen geteilt werden

Komposition verwenden wenn:

  • “ist-Teil-von” Beziehung vorliegt
  • Teile existieren nur mit dem Ganzen
  • Lebenszyklus des Teils ist an das Ganze gebunden

Vererbung verwenden wenn:

  • “ist-ein” Beziehung vorliegt
  • Unterklasse ist eine spezielle Form der Oberklasse
  • Code-Wiederverwendung und Polymorphie gewünscht

Vorteile und Nachteile

Vorteile von Klassenbeziehungen

  • Strukturierung: Klare Systemarchitektur
  • Wiederverwendung: Gemeinsame Funktionalität
  • Flexibilität: Leichte Erweiterbarkeit
  • Verständlichkeit: Reale Welt wird abgebildet
  • Wartbarkeit: Gezielte Änderungen möglich

Nachteile

  • Komplexität: Viele Beziehungen können unübersichtlich werden
  • Kopplung: Starke Abhängigkeiten können Probleme verursachen
  • Performance: Zu viele Objektverbindungen können langsam sein
  • Testbarkeit: Komplexe Beziehungen schwer zu testen

Häufige Prüfungsfragen

  1. Was ist der Unterschied zwischen Aggregation und Komposition? Aggregation: Teile können unabhängig existieren, Komposition: Teile existieren nur mit dem Ganzen.

  2. Erklären Sie die Multiplizität 1..*! Mindestens eins, beliebig viele Objekte können verbunden sein.

  3. Wann verwendet man Vererbung statt Komposition? Wenn eine “ist-ein” Beziehung besteht und Code-Wiederverwendung gewünscht ist.

  4. Was bedeutet bidirektionale Assoziation? Beide Klassen kennen sich gegenseitig und können aufeinander zugreifen.

Wichtigste Quellen

  1. https://de.wikipedia.org/wiki/Assoziation_(UML)
  2. https://refactoring.guru/design-patterns/composition-over-inheritance
  3. https://www.uml-diagrams.org/class-diagram-relationships.html
Zurück zum Blog
Share:

Ähnliche Beiträge