Wie kann ich in C# Unterklassen aufrufen?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Ich beziehe mich hier auf die Kommentare unter der Antwort von Dultus:
Und das, was Dultus schreibt ist - sorry - grober Unfug.

Das, was Du erreichen willst, ist eine klassische Anforderung der Objektorientierung.

Die OnUpdate-Methode muss virtual sein und die ableitenden Klasse überschreiben (override) sie:

static void Main(string[] args) {
      List<Module> Modules = new List<Module>();
      
      Modules.Add(new Flight());
      Modules.Add(new Speed());

      foreach (Module m in Modules) {
          m.OnUpdate();
      }
}

class Module {
    public virtual void OnUpdate() {
        Console.WriteLine("Called in Module");
    }
}

class Flight : Module {
    public override void OnUpdate() {
        base.OnUpdate();
        Console.WriteLine("Called in Flight");
    }
}

class Speed : Module {
    public override void OnUpdate() {
        base.OnUpdate();
        Console.WriteLine("Called in Speed");
    }
}

Man kann auch mit Reflection arbeiten, aber das ist unsicher, unnötig komplex und in 99,9...999% der Fälle völlig überflüssig.

Mit dynamic oder einem Interface Interface erreicht man dieses Ziel nicht, da sich beides nur mit der Existenz der Methode und ihren Aufruf beschäftigt. Man muss die Methode in den abgeleiteten Klassen aber immer noch überschreiben.

Einen Zwang zum Überschreiben der Methode und Aufrufen der Basis-Implementierung gibt es nicht, Du kannst aber mit einer zweiten abstrakten Methode tricksen.

Woher ich das weiß:Berufserfahrung
Learn2Code870 
Fragesteller
 01.10.2021, 21:25

Danke dir,

ich programmiere jetzt seit ungefähr 6 Jahren in Java und dort geht es genauso wie in meinem Code. Ich hab mich sowieso die ganze Zeit schon gefragt, wieso es so eine Kernfunktion der Objektorientierung nicht gibt, aber anscheinend schon, nur ein Wenig anders :)

0
Palladin007  01.10.2021, 21:27
@Learn2Code870

Ist eigentlich ziemlich gleich, aber bei C# sind die Methoden nicht automatisch virtual, sondern müssen explizit als virtual deklariert werden.

1
Learn2Code870 
Fragesteller
 01.10.2021, 21:44
@Palladin007

Ich sehe, dass bei die Methode, die mit virtual deklariert ist, an sich nicht aufgerufen wird. Kann man das auch noch ändern?

0
Palladin007  01.10.2021, 22:04
@Learn2Code870

Das "base" ist wie das "this", bloß für die Basis-Klasse.
Das "base.OnUpdate()" ruft also die Basis-Implementierung auf.

0
Dultus, UserMod Light   02.10.2021, 06:40

Ah, dann habe ich natürlich daran vorbeigearbeitet. Problem war, dass ich nicht direkt verstanden habe, was der FS erreichen wollte, weil mich die Fragestellung etwas irritiert hat.

0

Du kannst das Module einfach als Flight Klasse callen.

if (m is Flight)
(m as Flight).OnUpdate();

Wenn du das so meinst.

Woher ich das weiß:Berufserfahrung – 💻 Zertifizierter Sr. Cloud Engineer im IT-Consulting
Learn2Code870 
Fragesteller
 01.10.2021, 15:10

Danke, das funktioniert. Es bleibt aber nicht bei der einen Flight Klasse, sondern kann beliebig mehr werden. Gäbs da ne Lösung?

0
Learn2Code870 
Fragesteller
 01.10.2021, 15:30
@Dultus, UserMod Light
static void Main(string[] args) {
      List<Module> Modules = new List<Module>();
      
      Modules.Add(new Flight());
      Modules.Add(new Speed());

      foreach (Module m in Modules) {
          m.OnUpdate();
      }
}

class Module {
    public void OnUpdate() {
        Console.WriteLine("Called in Module");
    }
}

class Flight : Module {
    public void OnUpdate() {
        Console.WriteLine("Called in Flight");
    }
}

class Speed : Module {
    public void OnUpdate() {
        Console.WriteLine("Called in Speed");
    }
}

Ausgabe:

Called in Module
Called in Module

Was ich möchte ist, dass in der Konsole das ausgegeben wird:

Called in Module
Called in Flight
Called in Module
Called in Speed

Also im Endeffekt ist das Hauptziel, dass die Methode OnUpdate() in den Klassen Flight und Speed ebenfalls ausgeführt werden. In dem Fall hilft mir leider kein HardCode mit Casting, da ich in die Liste unbegrenzt viele Module hinzufügen möchte.

0
Palladin007  01.10.2021, 20:42
@Learn2Code870

Vergiss das bitte ganz schnell wieder, das ist Blödsinn
Was Du suchst ist eine Standard-Anforderung von der Objektorientierung

1
Dultus, UserMod Light   02.10.2021, 06:49
@Palladin007

Ah, sorry. Da war ich nicht mit dem Kopf ganz da. Leider habe ich Virtual Overrides in C# noch nicht verwendet. Heißt das, dass diese auch bei aufrufen der Masterclass die jeweilige Methode mit der der Subclass ersetzen?

0
Palladin007  02.10.2021, 12:03
@Dultus, UserMod Light

Das ist die Vererbung und Überschreibung von C#, bei Java geht's genauso, nur die Syntax ist hier und da etwas anders.

virtual heißt nur, dass die Methode überschrieben werden darf.
Bei Java darf jede Methode überschrieben werden und man muss das explizit verbieten.
Und das override ist bei Java genauso, nur eine andere Syntax. Da kann man auch die Basis-Implementierung aufrufen, heißt dann halt "super" und nicht "base".

Heißt das, dass diese auch bei aufrufen der Masterclass die jeweilige Methode mit der der Subclass ersetzen?

Bei Vererbung interessiert nicht, ob man die Basisklasse oder Ableitung hat, es zählt nur der Typ der Instanz. Und ob die Methode der Basis-Klasse auch aufgerufen wird, hängt von der Ableitung ab und wie sie das implementiert hat.

0
Dultus, UserMod Light   02.10.2021, 12:26
@Palladin007

Deshalb war der Gedanke, dass wenn ich Module nutze, dass ich ja deren Methode verwenden würde. Aber wenn das als Ableitung automatisch in die korrekte Subclass abgeleitet wird, ist das gut zu wissen. :-)

0