5

このようなものを持つ:

public abstract class AAA
{
  protected abstract virtual string ToString()    // Error
  {
    // Base Stuff
  }
}

public abstract class BBB : AAA
{
  public override string ToString()
  {
    // Use base.ToString();
    // More Stuff
  }
}

私は別の投稿(仮想クラスの抽象メソッド)を読みました 魔女は私の質問にかなり似ていましたが、少し違いがあります。AAA.ToString() に基本動作を持た、派生クラスに強制的にオーバーライドさせたいと思います。

このようなことができることは知っていますが(下にスクロール)、適切な方法を探していました。

public abstract class AAA
{
  public abstract string ToString();
  protected string ToString2()
  {
    // Base Stuff
  }
}

public class BBB : AAA
{
  public override string ToString()
  {
    // Use base.ToString2();
    // More Stuff
  }
}

おそらく IAAA インターフェイスを作成して、次のように BBB クラスを構築することもできます。

public class BBB : AAA, IAAA { ... }

しかし、私に正しく見えないでください。

4

3 に答える 3

5

あなたのアプローチ本質的に適切な方法です...

編集:

あなたの「仕様」は次のとおりです。

  1. デフォルトの動作
  2. 必要なオーバーライド

ここで、「デフォルトの動作」を常に実行したいように見えるので、必要です

public string ToString()
{
    // placeholder for some default behaviour

    string result = doToString();

    // placeholder for some more default behaviour

    return result;
}

protected abstract string doToString();

doToString()これは、基本クラスが一般的に行っていることを知っていて、派生クラスで実装を提供したい場合にのみ機能します。これは、テンプレート メソッド設計パターンとして知られています。

ただし、派生クラスの実装者に の実装を呼び出すように要求する方法を探している場合、これを行う方法はありません。オーバーライドを許可することで、派生クラスがその実装を制御できるようになります。 base.ToString()ToString()

常に を呼び出すという推奨事項を文書化できますbase.ToString()が、それだけです。

インターフェイスを使用すると、クラスのパブリック コントラクトが定義されます。「デフォルト」の実装を取得するには基本クラスから派生する必要があるため、これは Template Method パターンに勝る追加の利点はありません。

基本クラスで「デフォルトの動作」として提供しようとしているものについての詳細はありますか? 多分それはより良い解決策に役立つでしょう。参照されている質問を見ると、これは本質的に同じアプローチです。

于 2009-08-25T02:46:18.653 に答える
2

私はちょうど私が望んでいた動作を得るために何をすべきかを見つけました:

public abstract class AAA
{
  protected abstract string ToStringSpecific();
  protected string ToString()
  {
    // Base Stuff
    ...
    // Use this.ToStringSpecific();
  }
}

public class BBB : AAA
{
  protected override string ToStringSpecific()
  {
    // Specific Stuff
  }
}
于 2009-08-26T00:41:50.363 に答える
0

いいえ、現在仮想関数を抽象関数に変えることはできません。これを強制する唯一の方法は、あなたが提案したように、抽象的な別の関数を作成することです。これは間違いなくより適切なアプローチです (そして私はそれに同意します)。

于 2009-08-25T02:47:07.590 に答える