質問

本当に「ポリモーフィズム」なのかわかりません。とにかく質問... したがって、抽象クラスと、それを継承する2つの他のクラスがあります。

基本クラスの一部のコードには、基本クラスを拡張するクラス間で異なる変数があります。

それを行う最良の方法は何ですか? 「get」をオーバーライドします;方法?アーキテクチャを少し変更して、関数を基本クラスから値を渡す拡張クラスに呼び出します...

ここに例があります(コンパイルしません、私がそれをどのようにしたかについてのちょっとした例です):

public abstract class BaseAbstract class {

  ... some code ....

  // Here "listName" would change depending on the extending class
  protected List<Items> getAllItems(String listName) {

    Web.getList(listName);

    ... some code ...

  }

  protected abstract List<Items> getAllItems();

}

public class NewClass : BaseAbstract {
 protected override void getAllItems() {
    return getAllItems("ListNameOfNewClass");
 }
}

それは私がやった方法ですが、IMOを維持するのは本当に明確で簡単ではありません。

アイデアやコメントを歓迎します!

役に立ちましたか?

解決

おそらく次のようなものを選ぶでしょう:

public abstract class Base
{
    protected abstract string ListName { get; }
    public List<Item> GetItems()
    {
        return Web.GetList(ListName);
    }
}

public class Child : Base
{
    protected override string ListName
    {
        get { return "MyListName"; }
    }
}

他のヒント

継承よりも合成を優先する。

public class Base {
  private ItemListGetter itemListGetter; // assignment/initialization is up to you

  private List<Items> getAllItems() {  // this can now be inlined
    return itemListGetter.getList();
  }

}

これがサブクラス間のバリエーションの唯一の次元である場合、ここでは継承の必要はありません。必要に応じて適切なItemListGetterを設定するだけです。

おそらく次のアプローチを採用します。

public abstract class Base
{
    protected List<Items> getAllItems(String listName) 
    {
        // Implementation
    }

    public abstract List<Items> Items
    {
        get;
    }
}

public class NewClass : Base
{
    public override List<Items> Items
    {
        get
        {
            return base.getAllItems("ListNameOfNewClass");
        }
    }
}

これにより、内部で保護された機能(getAllItems)が公開されたメソッド/プロパティから分離され、NewClassを継承するすべてのクラスで引き続き使用できるようになります。

インターフェイスを変更し、純粋に頭がおかしいだけのプロパティとして公開しました!そして、あなたはそれができることを知らなかった場合のためにパーティーをしています...

それが正しい答えであるかどうかはわかりませんが、初期化中に継承クラスに設定する基本クラス保護変数を使用できますか?

eg:

class test
{
    protected string listName;

    protected void getAllItems() 
    {
        return getAllItems(listName);
    }
}

class test2 : test
{
    public test2()
    {
        base.listName = "MyUniqueList";
    }
}

3番目のコンポーネントを実装する方が理にかなっていると思います:

    public abstract class BaseClass {

        protected abstract IList<Item> getAllItems();
    }

    public class SubClass : BaseClass 
    {
        IItemsProvider itemsProvider;

        protected override IList<Item> getAllItems() 
        {
            return itemsProvider.getAllItems("filter");
        }
    }

    public interface IItemsProvider
    {
        IList<Item> getAllItems(string name);
    }

本当に継承を行いたい場合は、 ctacke's ソリューション。

一般的にあなたの問題は継承では解決されないようです。継承は、特別な動作を提供するためにのみ使用する必要があります。しかし、あなたの場合、それは設定の問題のようです。つまり、サブクラス化の必要なしに、外部から設定するプロパティ(つまり、リスト名)を提供する必要があります。

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