geometrische Konstruktion mit Gummi und zwei Stiften

Beziehungen zwischen Klassen - Assoziation, Aggregation und Komposition



Quellen:
M. Brenner, J. Schnaiter, "Softwareentwicklung mit Python", ZSL Freiburg, 2024
E. Fuchs, "Java 9 Grundlagen Programmierung", Herdt Verlag, 2017


In der objektorientierten Programmierung stehen Klassen häufig in Beziehung. Man unterscheidet drei Beziehungsarten mit unterschiedlicher Bindungsstärke: Assoziation, Aggregation und Komposition.

In diesem Artikel lernst Du die verschiedenen Beziehungsarten kennen, kannst sie unterscheiden und lernst sie in Python zu programmieren.

Klassen in Beziehung setzen Bindungsstärke

Assoziation
etwas in Verbindung 🔗 bringen

Zeichnung Fahrer und Auto

Auto *               1 Fahrer

Ein Auto hat einen (1) Fahrer. Ein Fahrer hat beliebig viele (* oder 0..*) Autos.

Die Klassen Fahrer und Auto stehen in Beziehung zueinander. Die Kardinalitätetn (1, *, ...) beschreiben die Anzahl. Die Klassen existieren unabhängig voneinander.

Aggregation
etwas anhäufen 🎨

Zeichnung Spieler und Mannschaft

Spieler *        1◇ Mannschaft

Ein Spieler ist Teil einer Mann­schaft. Eine Mann­schaft besteht aus beliebig vielen Spielern.

Das Ganze, die Mannschaft, besteht aus Spielern. Man beachte: Die Spieler können aber auch unabhängig von der Mannschaft existieren. Diese Kardinalität wird mit einer leeren Raute ◇ gekennzeichnet.

Komposition
etwas zusammensetzen 🎵

Zeichnung Haus und Raum

Raum 1..*        1◆ Haus

Ein Raum ist Teil eines Hauses. Ein Haus besteht aus mindestens einem Raum.

Wie bei der Aggregation besteht das Ganze, das Haus, aus mindestens einem Raum. Zusätzlich gilt aber: Ein Raum kann nicht ohne Haus existieren. Diese Kardinalität wird zusätzlich mit einer gefüllten Raute ◆ gekennzeichnet.

Aufgabe 1 Beziehungsarten trainieren

  1. Finde sechs weitere Klassenpaare wie Rechner und Server.
  2. Bestimme die Kardinalitäten zwischen den Klassen.
  3. Kennzeichne die Bindungsart (Assoziation, Aggregation oder Komposition) zwischen den Klassen.
  4. Ergänze Deine Aufzeichnungen um weitere Klassenpaare, so dass mindestens zwei von jeder Bindungsart vorhanden sind.
Beziehung zwischen Rechner und Server

Java programmieren Assoziation, Aggregation und Komposition

Die Assoziation

Bei der Assoziation enthält die Fahrerklasse eine Liste mit Autoobjekten.

public class Fahrer {
  private String name;
  private int alter;
  private ArrayList<Auto> autoListe; 

  //Konstruktor
  public Fahrer(String name, int alter, ArrayList<Auto> autoListe) {
    this.name = name;
    this.alter = alter;
    this.autoListe = autoListe;
  }

  //Get- und Set-Methoden
  public String getName() {
    return name;
  }
}
public class Auto {
  private String marke;
  private String modell;
  
  //Konstruktor
  public Auto(String marke, String modell) {
    this.marke = marke;
    this.modell = modell;
  }
  //Set- und Get-Methoden
  public String getMarke() {
    return marke;
  }
  public String getModell() {
    return modell;
  }
}

In der Testklasse wird eine Liste mit Objekten von Autos erzeugt. Ebenso wird ein Objekt der Klasse Fahrer erzeugt und diesem die Liste mit Autoobjekten übergeben.

public class Test {
  public static void main(String[] args) {
    ArrayList<Auto> autoListe = new ArrayList<>();
    autoListe.add(new Auto("VW", "Golf"));
    autoListe.add(new Auto("VW", "Polo"));
  
    Fahrer f1 = new Fahrer("Peter Mustermann", 25, autoListe);
  
    System.out.println("Eigentümer: "+f1.getName());
    System.out.print("Autos: ");
    for(Auto auto: autoListe) {
      System.out.print(auto.getMarke() +" "+auto.getModell());
    }
  }
}

Die Aggregation

Bei der Aggregation enthält die Mannschaftklasse eine Liste mit Spielerobjekten. Eine Mannschaft besteht aus beliebig vielen Spielern. Bei der Programmierung gibt es keinen Unterschied zur Assoziation.

public class Mannschaft {
  private ArrayList spielerListe;
	
  //Konstruktor
  public Mannschaft(ArrayList spielerListe) {
    this.spielerListe = spielerListe;
  }
	
  //Set- und get-Methoden
  public ArrayList getSpielerListe() {
    return spielerListe;
  }
}
public class Spieler {
  private String name;
  private String positon;
  private double marktwert;
  
  //Konstruktor
  public Spieler(String name, String position, double marktwert) {
    this.name = name;
    this.position = position;
    this.marktwert = marktwert;
  }
  //Set- und get-Methoden
  public String getName() {
    return name;
  }
  public String getPosition() {
    return position;
  }
  public double getMarktwert() {
    return marktwert;
  }
}

In der Testklasse wird eine Liste mit Objekten von Spielern erzeugt. Ebenso wird ein Objekt der Klasse Mannschaft erzeugt und diesem die Liste mit Spielerobjekten übergeben.

public class Test {
  public static void main(String[] args) {
    ArrayList mannschaftsListe = new ArrayList<>();
    mannschaftsListe.add(new Spieler("Ronaldo", "Mittelstürmer", 35));
    mannschaftsListe.add(new Spieler("Kimmich", "Def. Mittelfeld", 85));
    mannschaftsListe.add(new Spieler("Neymar", "Linksaußen", 90));
    
    Mannschaft m1 = new Mannschaft(mannschaftsListe);
    
    System.out.println("Die Mannschaft:");
    for (Spieler spieler: m1.getSpielerListe()) {
      System.out.println(spieler.getName()+" "+spieler.getPosition()+ " "+ spieler.getMarktwert()+ " Mio. €");
    }     
  }
}

Die Komposition

Bei der Komposition werden die Räume im Konstruktor der Klasse Haus erzeugt. Die Räume existieren also erst mit Erzeugung des Hauses.

public class Haus {
  private ArrayList raumListe = new ArrayList<>();
  
  //Konstruktor mit Erzeugung der Räume
  public Haus(String[] raumName) {
    for(int i=0; i<raumName.length; i++) {
      raumListe.add(new Raum(raumName[i]));
    }
  }
  //Set- und get-Methoden
  public ArrayList getRaumListe() {
    return raumListe;
  }
}
public class Raum {
  private String name;
  
  //Konstruktor
  public Raum(String name) {
    this.name = name;
  }

  //Set- und get-Methoden
  public String getName() {
    return name;
  }
}

In der Testklasse wird ein Array mit Raumnamen angelegt. Es wird ein Objekt der Klasse Haus angelegt und das Array mit den Raumnamen übergeben. Man beachte, dass in der Testklasse keine Räume als Objekte erzeugt werden.

Der Aufruf der einzelnen Räume geschieht über den Hausobjektnamen und der get-Methode für die Raumliste.

public class Test {
  public static void main(String[] args) {
    String[] raumName = {"Wohnen", "Essen", "Kochen"};
    
    //Ein Haus mit Räumen erzeugen.
    Haus h1 = new Haus(raumName);
    
    //Eine Liste der Räume ausgeben
    for(Raum raum: h1.getRaumListe()) {
      System.out.println(raum.getName());
    }
  }
}

Aufgabe 2 Beziehungsarten programmieren

Die Schafe sollen einen Schafstall bekommen.

  1. Erstelle die Klasse Schaf in dem package packageSchaf mit den Attributen name alter und gewicht.
  2. Erstelle automatisch einen Konstruktor mit allen Attributen und alle set- und get-Methoden.
  3. Erstelle die Klasse Schafstall mit einer ArrayList als Attribut vom Typ Schaf. Kennzeichne den Beziehungstyp zwische der Klasse Schaf und Schafstall als Kommentar in deinem Programm.
  4. Erstelle automatisch einen Konstruktor mit allen Attributen und alle set- und get-Methoden.
  5. In der Testklasse Testwird eine Liste mit Objekten von Schafen erzeugt. Ebenso wird ein Objekt der Klasse Schafstall erzeugt und diesem die Liste mit Schafobjekten übergeben.
  6. Liste mit einer for-each-Schleife alle Schafe Deines Stalls.
Zeichnung zweier Schafe

Aufgabe 3 Komposition programmieren

Die Pizza soll Zutaten bekommen. Eine Pizza besteht aus beliebig vielen Zutaten. Jede Zutat ist Teil einer Pizza. Darüber hinaus kann eine Zutat nicht ohne Pizza existieren.

Pizza Salami
  1. Erstelle die Klasse Zutat in dem package packagePizza mit den Attributen name und menge.
  2. Erstelle automatisch einen Konstruktor mit allen Attributen und alle set- und get-Methoden.
  3. Erstelle die Klasse Pizza mit folgenden Attributen: name und preis sowie einer ArrayList zutatenListe vom Typ Zutat. Kennzeichne den Beziehungstyp zwischen der Klasse Zutat und Pizza als Kommentar in deinem Programm.
  4. Erstelle automatisch einen Konstruktor mit allen Attributen und alle set- und get-Methoden. Lösche den Parameter zutatenListe und ersetze das Attribut zutatenListe durch den Methodenaufruf createZutatenListe(name).
  5. Schreibe die Methode createZutatenListe(String name). Erzeuge mit Hilfe der switch-case-Struktur die einzelnen Zutaten mit Mengen als Objekte.
  6. In der Testklasse Test wird eine Liste mit fünf verschiedenen Pizzen erzeugt. Gib alle Pizzen mit Preis und Zutaten als Menü aus.
  7. Zusatzaufgabe: Die Klasse Menue wird für verschiedene Menüs erstellt.

Wortliste und Satzbausteine



das Objekt, -e Objekte haben Eigenschaften (engl. states) und Fähigkeiten (engl. behaviors). Diese werden in einer zugehörigen Klasse festgelegt.
die Klasse, -n Eine Klasse beschreibt, welche Eigenschaften und Fähigkeiten ein Objekt haben darf und stellt somit den Bauplan von Objekten bereit.
die Methode, -en Fähigkeiten von Objekten werden in Methoden beschrieben.
das Attribut, -en Eigenschaften von Objekten werden in Attributen (Variablen) festgelegt.
der Modifier, ~ legt die Sichtbarkeit von Eigenschaften und Fähigkeiten fest, also ob diese bspw. privat oder öffentlich zugänglich sind
die set-, get-Me­thoden, - Methoden die die abgeschirmten Attribute setzen oder auslesen.
der Konstruk­tor, -en Methode welche die Initialisierung der Parameter bei Objekterzeugung ermöglicht
die Assozi­ation, -en Sie beschreibt eine einfache Bindung. Objekte verschiedener Klassen stehen in Beziehung, existieren aber unabhängig voneinander.
die Aggre­gation, -en Sie beschreibt eine stärkere Bindung. Objekte bestehen aus anderen Objekten.
die Kompo­sition, -en Sie beschreibt die stärkste Bin­dung. Objekte bestehen aus anderen Objek­ten, welche alleine nicht existieren können.