Domanda

Non sono sicuro che sia davvero un "polimorfismo" domanda ma comunque ... Quindi ho una classe astratta e altre 2 classi che ereditano da essa.

Alcuni codici della classe base hanno una variabile che sarebbe diversa tra le classi che estende la classe base.

Qual è il modo migliore per farlo? Sostituisci un " get " metodo? Cambia un po 'l'architettura per chiamare una funzione dalla classe base alla classe estesa che passerebbe il valore ...

Ecco un esempio (non verrà compilato, solo un piccolo esempio di come l'ho fatto):

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");
 }
}

È così che l'ho fatto, ma non mi sembra molto chiaro e facile mantenere l'IMO.

Qualsiasi idea o commento benvenuto!

È stato utile?

Soluzione

Probabilmente opterei per qualcosa del genere:

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"; }
    }
}

Altri suggerimenti

Preferisci la composizione rispetto all'ereditarietà.

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 questa è l'unica dimensione di variazione tra le tue sottoclassi, qui non è più necessario ereditare; basta stabilire il giusto ItemListGetter secondo necessità.

Probabilmente sceglierei il seguente approccio:

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");
        }
    }
}

Ciò mantiene la funzionalità protetta interna (getAllItems) separata dal metodo / proprietà esposti pubblicamente e significa anche che è ancora disponibile per tutte le classi che ereditano da NewClass.

Ho cambiato la tua interfaccia e l'ho esposta come una proprietà puramente per stordimento! E fai festa nel caso in cui non sapessi che potrebbe essere fatto ...

non sei sicuro che sia la risposta giusta, ma potresti avere una variabile protetta di classe base che hai impostato nelle classi ereditate durante l'inizializzazione?

es:

class test
{
    protected string listName;

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

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

Penso che avrebbe più senso implementare un terzo 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 vuoi davvero fare l'eredità, allora opterei per ctacke's soluzione.

In genere, tuttavia, il problema non sembra essere risolto con l'ereditarietà. L'ereditarietà dovrebbe essere utilizzata solo per fornire un comportamento specializzato. Nel tuo caso, tuttavia, sembra essere più un problema di configurazione. Ciò significa che è necessario fornire una proprietà (ovvero il nome elenco) che si configura dall'esterno, senza necessità di sottoclasse.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top