質問

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

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

私がすべき

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

編集:すべての回答をありがとう。これは起こるべきではないという私の疑念を確認しました。さらに調査した結果、メソッドはまったく使用されていなかったため、完全に削除しました。

役に立ちましたか?

解決

AbstractMethodAがChild-Bに適用されない場合、Child-BはParent-Aから継承してはなりません。

または、Child-BがParent-Aを継承し、AbstractMethodAが子に適用されない場合、逆の結果を得るには、親にも存在しないようにします。

Parent-Aにメソッドを配置するということは、そのメソッドがParent-Aとそのすべての子に適用されるということです。それがの意味の継承であり、それを使用して別の何かを意味する場合、コンパイラとの深刻な紛争になります。

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

別の方法は、とにかくChild-Bにメソッドを実装することですが、常に失敗を返す、例外をスローするなどの抜本的な処理を行わせます。それは機能しますが、親Aとして扱うことを持っているものが本当にであることを発信者が知る必要があることを意味するので、きれいなデザインではなくちょっとした障害とみなされるべきです子Bであるため、AbstractMethodAを呼び出さないでください。基本的に、オブジェクト指向継承の主な利点であるポリモーフィズムを破棄しました。個人的には、基本クラスで例外をスローする実装よりもこのようにする方が好きです。なぜなら、子クラスは「誤って」「できない」からです。 " forgetting"によるひどい振る舞いメソッドを実装します。それを実装する必要があり、機能しないように実装する場合は明示的に実装します。悪い状況は騒々しいはずです。

他のヒント

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

一般的に言えば、最初にすべての抽象メソッドを実装できない場合は、抽象クラスから継承すべきではないと思いますが、それを行うのが理にかなっている状況があることを理解しています、(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.");
}

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

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

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

Delphiのことはあまり知りません(まったくありません:))、しかし、 JavaおよびCOMでは、クラスは複数のインターフェイスを「実装」できます。 C ++では、抽象クラスを多重継承することによってのみこれを実現できます。

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top