using System; using _10_Override.Krokodile; namespace _10_Override; public class Override { private static void Main(string[] args) { Leistenkrokodil leistenkrokodil = new Leistenkrokodil("Grau bis graubraun oder goldbraun"); Console.WriteLine($"Farbe des Krokodils: {leistenkrokodil.Farbe}"); // Mit dem '$' vor der Zeichenkette machen wir eine "String-Interpolation". Das heißt, wir können Variablen in { } direkt in die Zeichenkette schreiben. leistenkrokodil.ZeigeInfoZumLebensraum(); // die abstrakte Methode, die in der Subklasse durch Überschreiben implementiert wurde. leistenkrokodil.Schwimmen(); // Virtuelle Methode, die überschrieben wurde. leistenkrokodil.ImSchlammLiegen(); // Eine in der Subklasse erstellte Methode. Nilkrokodil nilkrokodil = new Nilkrokodil("Oberseits dunkel-olivfarben, der Bauch ist einheitlich porzellanfarben"); Console.WriteLine($"Farbe des Krokodils: {nilkrokodil.Farbe}"); // Beispiel zu 'new' -> Wir bekommen alles in Großbuchstaben. nilkrokodil.ZeigeInfoZumLebensraum(); nilkrokodil.Schwimmen(); // Beispiel zu 'new' -> Es ist hier noch kein Unterschied zum Override sichtbar. nilkrokodil.ImGrasLiegen(); Console.WriteLine(); Console.WriteLine("Ausgabe aller Elemente der Krokodil-Liste:"); foreach (Krokodil k in Krokodil.KrokodilListe) { Console.WriteLine(k.GetType().Name); // Mit "Reflection" den Namen des instanziierten Datentyps abfragen. Console.WriteLine(k.Farbe); // Hier greift 'new' nicht, da der Typ die Basisklasse ist. In diesem Fall würde nur 'override' funktionieren. k.ZeigeInfoZumLebensraum(); // Da diese Methode in der Basisklasse definiert ist, verfügen auch alle Subklassen darüber. // Die Methode wird aber je nach Subklasse ein anderes Verhalten zeigen, da sie dort überschrieben wurde. k.Schwimmen(); // Diese Methode haben wir einmal überschrieben und einmal nur ausgeblendet. Daher werden wir einmal die Ausgabe aus der überschreibenden Variante sehen und einmal die Ausgabe aus der Basisklasse. // Möchte ich Member aufrufen, die es nur in den Subklassen gibt, muss konvertiert (gecastet) werden: //((Leistenkrokodil)k).ImSchlammLiegen(); // Verursacht eine Exception, wenn nicht gecastet werden kann. //(k as Nilkrokodil)?.ImGrasLiegen(); // 'as' gibt Null zurück, wenn nicht gecastet werden kann. '?' prüft auf Null. // Mit 'is' prüfen wir, ob das Krokodil ein Leistenkrokodil ist. Wenn ja, wird gecastet und das Ergebnis 'l' zugewiesen: if (k is Leistenkrokodil l) l.ImSchlammLiegen(); // Mit 'is' prüfen wir, ob das Krokodil ein Nilkrokodil ist. Wenn ja, wird gecastet und das Ergebnis 'n' zugewiesen: if (k is Nilkrokodil n) { n.ImGrasLiegen(); n.Schwimmen(); // Nach dem Cast wird der Typ der Subklasse verwendet und wir sehen die Ausgabe aus der 'new'-Methode. } } } }