Вопрос

Я не уверен, что это действительно вопрос "полиморфизма", но в любом случае...Итак, у меня есть абстрактный класс и 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.

Я изменил ваш интерфейс и выставил его как свойство исключительно из-за безрассудства! И вечеринка на тот случай, если ты не знал, что это можно сделать ...

не уверен, что это правильный ответ, но у вас могла бы быть переменная, защищенная базовым классом, которую вы устанавливаете в унаследованных классах во время инициализации?

например:

class test
{
    protected string listName;

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

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

Я думаю, что было бы разумнее реализовать третий компонент:

    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