# Vererbung, Überschreiben und Polymorphie in C# ## Ziel dieser Einheit In dieser Einheit lernst du: - was abstrakte Klassen sind - wie Vererbung in C# funktioniert - was der Unterschied zwischen `override` und `new` ist - wie Polymorphie funktioniert - warum Casting notwendig sein kann --- ## 1. Grundidee: Vererbung Definition: Klassen können von anderen Klassen erben. Dabei übernehmen sie Eigenschaften und Methoden. Begriffe: - Basisklasse (Elternklasse) - Subklasse (Kindklasse) - Vererbung --- ## 2. Die Basisklasse: Krokodil public abstract class Krokodil Erläuterung: - abstrakte Klasse → kann nicht instanziiert werden - dient als gemeinsame Grundlage --- ### Property public string Farbe { get; private set; } - Property mit unsichtbarem Backing-Field - Setter ist privat --- ### Konstruktoren protected Krokodil() : this("Keine Farbe") - Konstruktor-Verkettung mit `this` protected Krokodil(string farbe) { Farbe = farbe; KrokodilListe.Add(this); } - jedes Objekt wird automatisch in eine Liste eingefügt --- ### Abstrakte Methode public abstract void ZeigeInfoZumLebensraum(); Erläuterung: - muss in allen Unterklassen implementiert werden --- ### Virtuelle Methode public virtual void Schwimmen() { Console.WriteLine("Ich schwimme im Wasser."); } Erläuterung: - kann überschrieben werden - muss aber nicht --- ## 3. Klasse Leistenkrokodil public sealed class Leistenkrokodil : Krokodil Erläuterung: - `sealed` → keine weitere Vererbung möglich --- ### Überschreiben abstrakter Methoden public override void ZeigeInfoZumLebensraum() Erläuterung: - `override` ist verpflichtend - Verhalten wird neu definiert --- ### Überschreiben virtueller Methoden public override void Schwimmen() { base.Schwimmen(); Console.WriteLine("Ich schwimme im Salzwasser."); } Erläuterung: - `base` greift auf Verhalten der Basisklasse zu --- ### Eigene Methode public void ImSchlammLiegen() - nur in dieser Klasse verfügbar --- ## 4. Klasse Nilkrokodil public class Nilkrokodil : Krokodil --- ### Überschreiben mit sealed public sealed override void ZeigeInfoZumLebensraum() - verhindert weiteres Überschreiben --- ### Methode mit new public new void Schwimmen() Erläuterung: - `new` blendet die Methode aus - kein echtes Überschreiben --- ### Eigene Methode public void ImGrasLiegen() --- ### Property mit new public new string Farbe => base.Farbe.ToUpper(); Erläuterung: - Getter wurde neu definiert - gibt Wert in Großbuchstaben zurück - Expression Bodied Member --- ## 5. Anwendung in der Main-Methode Leistenkrokodil leistenkrokodil = new Leistenkrokodil("..."); Console.WriteLine($"Farbe des Krokodils: {leistenkrokodil.Farbe}"); --- ### Methodenaufrufe leistenkrokodil.ZeigeInfoZumLebensraum(); leistenkrokodil.Schwimmen(); leistenkrokodil.ImSchlammLiegen(); - implementierte Methode - überschriebene Methode - eigene Methode --- ### Nilkrokodil Nilkrokodil nilkrokodil = new Nilkrokodil("..."); Console.WriteLine($"Farbe des Krokodils: {nilkrokodil.Farbe}"); --- ### Verhalten von new nilkrokodil.Schwimmen(); - kein Unterschied sichtbar bei direkter Verwendung --- ## 6. Polymorphie mit Basisklasse foreach (Krokodil k in Krokodil.KrokodilListe) --- ### Reflection Console.WriteLine(k.GetType().Name); - tatsächlicher Typ zur Laufzeit --- ### Verhalten von override k.ZeigeInfoZumLebensraum(); - abhängig von der Subklasse --- ### Verhalten von new Console.WriteLine(k.Farbe); Erläuterung: - nur Basisklassen-Version wird verwendet - `new` greift hier nicht --- ### Unterschied sichtbar machen k.Schwimmen(); - einmal überschrieben - einmal nur ausgeblendet --- ## 7. Casting ### Direktes Casting ((Leistenkrokodil)k).ImSchlammLiegen(); - kann Exception werfen --- ### Sicheres Casting mit as (k as Nilkrokodil)?.ImGrasLiegen(); - gibt null zurück - `?` prüft auf null --- ### Casting mit is if (k is Leistenkrokodil l) l.ImSchlammLiegen(); --- if (k is Nilkrokodil n) { n.ImGrasLiegen(); n.Schwimmen(); } - kombiniert Typprüfung und Casting --- ## 8. Wichtige Konzepte im Überblick ### abstract - MUSS überschrieben werden --- ### virtual - KANN überschrieben werden --- ### override - echtes Überschreiben --- ### new - nur Ausblenden --- ### sealed - verhindert weiteres Überschreiben --- ### Polymorphie - Verhalten abhängig vom tatsächlichen Objekttyp --- ## Zusammenfassung - Vererbung ermöglicht Wiederverwendung von Code - abstrakte Methoden müssen implementiert werden - virtuelle Methoden können überschrieben werden - `override` und `new` verhalten sich unterschiedlich - Polymorphie bestimmt das Verhalten zur Laufzeit - Casting ist notwendig für Zugriff auf Subklassen --- ## Verständnisfragen - Was ist der Unterschied zwischen `override` und `new`? - Wann wird eine Methode überschrieben? - Warum funktioniert `new` bei Polymorphie anders? - Wann ist Casting notwendig? - Was macht `sealed`? ``