2

私は、多くのクラスとこれらのクラスの多くの抽象メソッドを持つ大規模なコードベースを扱っています。次のような状況でどうしたらいいかという人の意見に興味があります。

抽象メソッドを持つクラスParent-Aがある場合。子供は2人だけです。Child-BがAbstractMethodAを実装しているが、Child-Bは適用されないため実装していない場合。

するべきか

  1. 親からabstractキーワードを削除し、仮想または動的を使用しますか?
  2. メソッドの空の実装を提供します。
  3. 呼び出された場合にエラーを発生させる実装を提供します。
  4. 警告を無視します。

編集:すべての答えをありがとう。これは起こらないはずだという私の疑いを確認しました。さらに調査したところ、メソッドがまったく使用されていなかったことが判明したため、完全に削除しました。

4

6 に答える 6

9

AbstractMethodA が Child-B に適用されない場合、Child-B は Parent-A から継承されるべきではありません。

または、対比すると、Child-B が Parent-A から継承し、AbstractMethodA が子に適用されない場合、親にも存在しないはずです。

親 A にメソッドを配置することで、そのメソッドが親 A とそのすべての子に適用されることになります。それが継承の意味であり、それを別の意味で使用すると、コンパイラとの深刻な論争に発展します。

[編集 - とはいえ、メソッドが適用される場合、Mladen Prajdic の答えは問題ありませんが、関連する 1 つ以上のクラスに対しては何もしないでください。何もしないメソッドは、適用されないメソッドと同じではありませんが、「適用されない」とは同じことを意味しないかもしれません]

もう 1 つの手法は、とにかく Child-B にメソッドを実装することですが、常に失敗を返す、または例外をスローするなどの抜本的な処理を行うようにします。これは機能しますが、親 A として扱っているものが本当にchild-B であるため、AbstractMethodA を呼び出すべきではありません。基本的に、OO 継承の主な利点であるポリモーフィズムを破棄しました。個人的には、基本クラスに例外をスローする実装を実装するよりも、このようにする方が好きです。これは、メソッドの実装を「忘れる」ことによって、子クラスが「誤って」悪い動作をすることがないためです。実装する必要があり、実装しても機能しない場合は、明示的に実装します。悪い状況はうるさいはずです。

于 2008-11-28T12:44:09.340 に答える
2

子孫への実装が必須でない場合は、1+2 (つまり、先祖に空の仮想メソッド) を使用する必要があります。

于 2008-11-28T12:47:11.707 に答える
1

一般的に言えば、そもそもすべての抽象メソッドを実装できない場合は、抽象クラスから継承するべきではないと思いますが、それを行うことが理にかなっている状況がいくつかあることは理解しています (を参照)。 Stream クラスとその実装)。

NotImplementedException をスローするこれらの抽象メソッドの実装を作成するだけでよいと思います。

ObsoleteAttribute を使用して、その特定のメソッドを呼び出すとコンパイル時エラーが発生するようにすることもできます (もちろん、NotImplementedException をスローすることに加えて)。ObsoleteAttribute はこれに使用することを意図したものではないことに注意してください。ただし、意味のあるエラー メッセージとコメントを使用すれば問題ないと思います。

必須のコード例:

[Obsolete("This class does not implement this method", true)]
public override string MyReallyImportantMethod()
{
    throw new NotImplementedException("This class does not implement this method.");
}
于 2008-11-28T13:24:25.750 に答える
0

基本クラスで仮想空にし、子でオーバーライドします。

于 2008-11-28T12:43:21.527 に答える
0

インターフェイスを使用できます。次に、子 A と子 B の両方が異なるメソッドを実装し、親 A から継承することができます。インターフェイスは、クラスに強制的に実装させるという点で、抽象メソッドのように機能します。

于 2008-11-28T12:46:28.137 に答える
0

A のいくつかのサブクラス (B1、B2、...) が、他のもの (C1、C2、...) とは異なるメソッドのサブセットに使用されている場合、A は B と C に分割できると言うかもしれません。

Delphi についてはよくわかりませんが (まったくわかりません :))、たとえば Java や COM と同じように、クラスは複数のインターフェイスを「実装」できると思いました。C++ では、これは複数の抽象クラスを継承することによってのみ実現できます。

より具体的には、(抽象メソッドを使用して) 2 つの抽象クラスを作成し、継承ツリーを変更します。

それが不可能な場合、回避策は「アダプター」である可能性があります。すべての B メソッドが空で実装された (そして呼び出し時に警告が生成される) 中間クラス A_nonB_ と、A_nonC_ です。次に、継承ツリーを変更して問題を解決します。B1、B2、... A_nonC_ から継承し、C1、C2、... A_NonB_ から継承します。

于 2008-11-28T13:01:37.123 に答える