dedlfix: Uebung Abstrakte Klassen mit abstrakten Parametern

Beitrag lesen

Hi!

Generic types sollte dir einen guten Einstiegspunkt liefern.

Inwiefern soll ihm das helfen? Ein Generic Type ist in seinem Szenario ähnlich der Verwendung eines abstrakten Typs, nur dass eben alle Typen und nicht nur von Document abgeleitete verwendet werden können. Er hat dann immer noch keine Einschränkung auf bestimmte Typen in den print-Methoden der abgeleiteten Klassen - im Gegenteil. Das Problem bleibt, dass die Methodensignaturen durch Einschränkungen auf andere/konkretere Typen nicht mehr die selben sind und damit nicht die abstrakte print-Methode treffen.

Ich hatte das auch in Erwägung gezogen, aber mit C# habe ich nichts hinbekommen. Vielleicht kennt Java andere Möglichkeiten ... Das war jedenfalls meine (C#-)Idee:

public abstract class Document { }
  public class Text : Document { } // der : ist das Äquivalent zu Javas extends
  public class Drawing : Document { }

public abstract class Printer {
    public abstract void print<T>(T doc) where T : Document;
    // mit dem where kann man den generischen Typ einschränken
    // dürfte Javas Bounded Type Parameters entsprechen:
    // public abstract void print<T extends Document>(T doc);
  }

public class LinePrinter : Printer {
    public override void print<T>(T doc) where T : Text { }
    // hier meckert der C#-Compiler, weil er die where-Einschränkung
    // generell aus der geerbten Methode übernimmt.
  }

public class Plotter : Printer {
    public override void print<T>(T doc) where T : Drawing { }
  }

Es geht auch nicht:

public abstract class Printer {
    public abstract void print(Document doc);
  }

public class LinePrinter : Printer {
    public override void print<T>(T doc) where T : Text { }
  }

Der Compiler findet, die beiden print-Methoden überschreiben sich nicht. Auch in folgendem Versuch nicht (weder mit Text noch mit Document als Typ im where-Constraint - diesmal an der Klasse statt der print-Methode):

public abstract class Printer {
    public abstract void print(Document doc);
  }

public class LinePrinter<T> : Printer where T : Text {
    public override void print(T doc) { }
  }

Lo!