2 Stimmen

Standardimplementierungen von abstrakten Methoden

Ich habe es mit einer großen Codebasis zu tun, die viele Klassen und viele abstrakte Methoden für diese Klassen enthält. Ich bin an Meinungen darüber interessiert, was ich in der folgenden Situation tun sollte.

Wenn ich eine Klasse Parent-A mit einer abstrakten Methode habe. Es wird nur 2 Kinder geben. Wenn Kind-B implementiert AbstractMethodA aber Kind-B nicht, da es nicht gilt.

Sollte ich

  1. Entfernen Sie das abstrakte Schlüsselwort von parent und verwenden Sie virtual oder dynamic?
  2. Stellen Sie eine leere Implementierung der Methode bereit.
  3. Stellen Sie eine Implementierung bereit, die bei einem Aufruf einen Fehler auslöst.
  4. Ignorieren Sie die Warnung.

Edit: Danke für die vielen Antworten. Es hat meinen Verdacht bestätigt, dass dies nicht passieren sollte. Nach weiteren Untersuchungen stellte sich heraus, dass die Methoden überhaupt nicht verwendet wurden, also habe ich sie vollständig entfernt.

9voto

Steve Jessop Punkte 264569

Wenn AbstractMethodA nicht für Child-B gilt, dann sollte Child-B nicht von Parent-A erben.

Oder umgekehrt: Wenn Child-B von Parent-A erbt und AbstractMethodA nicht für das Child gilt, dann sollte es auch nicht im Parent enthalten sein.

Wenn Sie eine Methode in Parent-A einfügen, bedeutet dies, dass die Methode für Parent-A und alle seine Kinder gilt. Das ist die Vererbung bedeutet und wenn Sie es für etwas anderes verwenden, werden Sie in einen ernsthaften Streit mit Ihrem Compiler geraten.

[Edit - das heißt, die Antwort von Mladen Prajdic ist in Ordnung, wenn die Methode anwendbar ist, sollte aber nichts für eine oder mehrere der beteiligten Klassen tun. Eine Methode, die nichts tut, ist IMO nicht dasselbe wie eine Methode, die nicht anwendbar ist, aber vielleicht meinen wir mit "nicht anwendbar" nicht dasselbe].

Eine andere Technik besteht darin, die Methode in Child-B zu implementieren, sie aber etwas Drastisches tun zu lassen, wie z. B. immer einen Fehler zurückgeben oder eine Ausnahme auslösen. Das funktioniert, sollte aber eher als Pfusch denn als sauberes Design betrachtet werden, da es bedeutet, dass der Aufrufer wissen muss, dass das Ding, das er als Parent-A behandelt, wirklich ein Kind-B und sollten daher nicht AbstractMethodA aufrufen. Im Grunde genommen haben Sie den Polymorphismus verworfen, der der Hauptvorteil der OO-Vererbung ist. Ich persönlich bevorzuge diese Vorgehensweise gegenüber einer Implementierung in der Basisklasse, die eine Ausnahme auslöst, weil sich dann eine Kindklasse nicht "versehentlich" schlecht verhalten kann, indem sie "vergisst", die Methode überhaupt zu implementieren. Sie muss sie implementieren, und wenn sie sie so implementiert, dass sie nicht funktioniert, dann tut sie das explizit. Eine schlechte Situation sollte laut sein.

2voto

Oliver Giesen Punkte 8859

Wenn die Implementierung in Nachkommen nicht zwingend erforderlich ist, sollten Sie sich für 1+2 entscheiden (d. h. leere virtuelle Methode im Vorfahren).

1voto

Tamas Czinege Punkte 114595

Ich denke, dass man im Allgemeinen nicht von einer abstrakten Klasse erben sollte, wenn man nicht in der Lage ist, alle abstrakten Methoden zu implementieren, aber ich verstehe, dass es einige Situationen gibt, in denen es trotzdem sinnvoll ist, dies zu tun (siehe die Stream-Klasse und ihre Implementierungen).

Ich denke, Sie sollten einfach Implementierungen dieser abstrakten Methoden erstellen, die eine NotImplementedException auslösen.

Sie können auch versuchen, ObsoleteAttribute zu verwenden, so dass der Aufruf dieser bestimmten Methode ein Kompilierzeitfehler wäre (zusätzlich zum Auslösen von NotImplementedException natürlich). Beachten Sie, dass ObsoleteAttribute nicht unbedingt dafür gedacht ist, aber ich denke, wenn Sie eine aussagekräftige Fehlermeldung mit Kommentaren verwenden, ist es in Ordnung.

Obligatorisches Code-Beispiel:

[Obsolete("This class does not implement this method", true)]
public override string MyReallyImportantMethod()
{
    throw new NotImplementedException("This class does not implement this method.");
}

0voto

Mladen Prajdic Punkte 15257

In der Basisklasse virtuell leer machen und in den untergeordneten Klassen überschreiben.

0voto

Lars Truijens Punkte 41774

Sie könnten Schnittstellen verwenden. Dann können Child-A und Child-B unterschiedliche Methoden implementieren und trotzdem von Parent-A erben. Schnittstellen funktionieren wie abstrakte Methoden, da sie die Klasse zwingen, sie zu implementieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X