questão C # básica Polimorfismo
-
06-07-2019 - |
Pergunta
Eu não tenho certeza que é realmente uma questão "polimorfismo", mas de qualquer maneira ... Então, eu tenho uma classe abstrata e 2 outras classes que herdam-lo.
Alguns código da classe base tem uma variável que seria diferente entre as classes que estende a classe base.
Qual é a melhor maneira de fazer isso? Substituir um método "get"? Mudar a arquitetura um pouco para chamar uma função a partir da classe base para a classe estendida que iria passar o valor ...
Aqui está um exemplo (não irá compilar, apenas um pequeno exemplo de como eu fiz isso):
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");
}
}
Isso é como eu fiz isso, mas ele não se sente muito claro e fácil de manter IMO.
Qualquer ideia ou comentário bem-vindos!
Solução
eu provavelmente optar por algo como isto:
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"; }
}
}
Outras dicas
Prefere composição sobre herança.
public class Base {
private ItemListGetter itemListGetter; // assignment/initialization is up to you
private List<Items> getAllItems() { // this can now be inlined
return itemListGetter.getList();
}
}
Se esta é a única dimensão de variação entre suas subclasses, não há mais a necessidade de herança aqui; apenas estabelecer a ItemListGetter direita, conforme necessário.
eu provavelmente ir para abordagem o seguinte:
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");
}
}
}
Isso mantém a funcionalidade protegida interna (getTodosOsItens) separar a partir do exposto publicamente método / propriedade, e significa também que o seu ainda disponível para todas as classes que herdam de NewClass.
Eu mudei sua interface e expôs-lo como uma propriedade puramente por teimosia! E festa apenas no caso de você não sabia que poderia ser feito ...
Não é certo que é a resposta certa, mas você pode ter uma variável protegida classe base que você definir nas classes herdadas durante a inicialização?
por exemplo:
class test
{
protected string listName;
protected void getAllItems()
{
return getAllItems(listName);
}
}
class test2 : test
{
public test2()
{
base.listName = "MyUniqueList";
}
}
Eu acho que faria mais sentido implementar um terceiro componente:
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);
}
Se você realmente quer fazer a herança, então eu optar por ctacke de solução.
Geralmente, no entanto o seu problema não parece ser resolvido com a herança. Herança deve apenas ser utilizado para fornecer o comportamento especializado. No seu caso, no entanto, parece mais ser um problema de configuração. Ou seja, você deve fornecer uma propriedade (ou seja, a lista de nomes) que você configurar a partir do exterior, sem qualquer necessidade de subclassificação.