CS_LEVEL_24_SOLUTION - OnlyCook/abitur-elite-code GitHub Wiki

Level 24 – Musterlösung: Flughafen-Infrastruktur (Teil 1)

Lösung

public class Flug
{
    private string flugNr;
    private string ziel;
    private DateTime startDatum;
    private string gate;
    private int maxPassagiere;
    private double basisPreis;
 
    public Flug(string flugNr, string ziel, DateTime startDatum, string gate, int max, double preis)
    {
        this.flugNr = flugNr;
        this.ziel = ziel;
        this.startDatum = startDatum;
        this.gate = gate;
        this.maxPassagiere = max;
        this.basisPreis = preis;
    }
}
 
public class Passagier
{
    private int passagierID;
    private string name;
    private string ticketNummer;
    private static int autowert = 0;
    private Flug flug;
    private List<Gepaeckstueck> gepaeck;
 
    public Passagier(string name, string ticketNummer, Flug f)
    {
        this.passagierID = ++autowert;
        this.name = name;
        this.ticketNummer = ticketNummer;
        this.flug = f;
        this.gepaeck = new List<Gepaeckstueck>();
    }
}
 
public class GepaeckWagen
{
    private Gepaeckstueck gepaeck;
    private GepaeckWagen naechsterWagen;
 
    public GepaeckWagen(Gepaeckstueck g)
    {
        this.gepaeck = g;
        this.naechsterWagen = null;
    }
 
    public void Anhaengen(GepaeckWagen wagen)
    {
        if (naechsterWagen == null)
        {
            naechsterWagen = wagen;
            return;
        }
 
        GepaeckWagen aktuell = naechsterWagen;
        while (aktuell.GetNaechsterWagen() != null)
        {
            aktuell = aktuell.GetNaechsterWagen();
        }
        aktuell.SetNaechsterWagen(wagen);
    }
 
    public GepaeckWagen GetNaechsterWagen()
    {
        return naechsterWagen;
    }
 
    public void SetNaechsterWagen(GepaeckWagen wagen)
    {
        naechsterWagen = wagen;
    }
}

Erklärung

Willkommen in Sektion 6

Ab jetzt dreht sich alles um einen Flughafen. Das Klassendiagramm wächst über die nächsten Level kontinuierlich – Flug, Passagier und GepaeckWagen sind der Einstieg. In diesem Level geht es darum, diese drei Klassen sauber nach Diagramm umzusetzen. Wirklich Neues ist hier wenig dabei – der Fokus liegt auf Präzision.


Flug – sechs Felder, ein Getter

public class Flug
{
    private string flugNr;
    private string ziel;
    private DateTime startDatum;
    private string gate;
    private int maxPassagiere;
    private double basisPreis;
 
    public Flug(string flugNr, string ziel, DateTime startDatum, string gate, int max, double preis)
    {
        this.flugNr = flugNr;
        this.ziel = ziel;
        this.startDatum = startDatum;
        this.gate = gate;
        this.maxPassagiere = max;
        this.basisPreis = preis;
    }
}

Hier gibt es nichts Überraschendes: alle sechs Felder werden im Konstruktor zugewiesen.


Passagier – Autowert und Gepäckliste

Autowert

private static int autowert = 0;
 
public Passagier(string name, string ticketNummer, Flug f)
{
    this.passagierID = ++autowert;
    ...
}

Das Muster kennst du bereits aus Sektion 4: autowert ist static, gehört also zur Klasse selbst und nicht zu einem einzelnen Objekt. Jedes Mal, wenn ein neuer Passagier erstellt wird, wird autowert zuerst um 1 erhöht (++autowert) und dann als ID vergeben. Das ergibt eine fortlaufende, eindeutige Nummerierung – genau wie bei echten Passagier-IDs.

Wichtig: ++autowert (Pre-Inkrement) bedeutet, dass der Wert vor der Zuweisung erhöht wird. Der erste Passagier bekommt also die ID 1, nicht 0.

Gepäckliste initialisieren

this.gepaeck = new List<Gepaeckstueck>();

Das Feld gepaeck ist vom Typ List<Gepaeckstueck>. Es muss im Konstruktor mit new initialisiert werden – sonst wäre es null und spätere Zugriffe würden abstürzen.


GepaeckWagen – die verkettete Liste

Du kennst dieses Prinzip schon aus Level 9 (Güterzug mit Waggons). Hier heißen die Klassen anders, aber der Aufbau ist identisch: jeder GepaeckWagen kennt seinen Nachfolger (naechsterWagen), und durch dieses Verketten entsteht eine Kette von beliebiger Länge.

Warum macht man das so, statt einfach eine List<GepaeckWagen> zu nehmen? Im echten Abiturkontext wird die verkettete Liste als eigenes Modellierungsmittel eingesetzt – sie bildet eine physische Kette (wie Gepäckwagen am Flughafen) direkt im Code ab, ohne dass eine externe Listenklasse nötig ist.

Konstruktor

public GepaeckWagen(Gepaeckstueck g)
{
    this.gepaeck = g;
    this.naechsterWagen = null;
}

Ein neuer Wagen kennt noch keinen Nachfolger – naechsterWagen wird explizit auf null gesetzt.

Anhaengen

public void Anhaengen(GepaeckWagen wagen)
{
    if (naechsterWagen == null)
    {
        naechsterWagen = wagen;
        return;
    }
 
    GepaeckWagen aktuell = naechsterWagen;
    while (aktuell.GetNaechsterWagen() != null)
    {
        aktuell = aktuell.GetNaechsterWagen();
    }
    aktuell.SetNaechsterWagen(wagen);
}

Die Methode wird immer auf dem ersten Wagen der Kette aufgerufen und hängt den neuen Wagen ans Ende. Der Ablauf:

  1. Ist naechsterWagen noch null, ist die Kette nach diesem Wagen leer – der neue Wagen wird direkt angehängt, fertig.
  2. Andernfalls: mit aktuell durch die Kette laufen, bis ein Wagen gefunden wird, dessen naechsterWagen null ist. Das ist das aktuelle Ende der Kette.
  3. Dort wird der neue Wagen angehängt.