Question

I'm not sure it's really a "polymorphism" question but anyway... So I have an abstract class and 2 other classes that inherit from it.

Some code from the base class have a variable that would be different between classes that extends the base class.

What's the best way to do that? Override a "get" method? Change the architecture a little to call a function from the base classe to the extended class that would pass the value...

Here's an example (it won't compile, just a little example on how I did it) :

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

That's how I did it, but it doesn't feel really clear and easy to maintain IMO.

Any idea or comment welcome!

Was it helpful?

Solution

I'd probably opt for something like this:

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

OTHER TIPS

Prefer Composition Over Inheritance.

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

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

}

If this is the only dimension of variation between your subclasses, there's no longer a need for inheritance here; just establish the right ItemListGetter as needed.

I would probably go for the following approach:

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

This keeps the internal protected functionality (getAllItems) separate from the publicly exposed method / property, and also means that its still available to any classes which inherit from NewClass.

I've changed your interface and exposed it as a property purely out of pig-headedness! And party just in case you didnt know it could be done...

not sure it's the right answer, but you could have a base class protected variable that you set in the inherited classes during initialization?

eg:

class test
{
    protected string listName;

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

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

I think it would make more sense implementing a third component:

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

If you really want to do the inheritance, then I'd opt for ctacke's solution.

Generally however your problem doesn't seem to be solved with inheritance. Inheritance should just be used to provide specialized behavior. In your case however it seems more to be a configuration issue. Meaning you should provide a property (i.e. the list-name) which you configure from outside, without any need for subclassing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top