1

Trying to understand how to access the methods of a sub-class when the list is typed as the superclass. This should be basic polymorphism, but I'm getting confused.

public class super
{ 
  public Boolean isSuper()
  {
    return true;
  }
}

public class sub : super
{ 
  public Boolean isSuper()
  {
    return false;
  }
}

Now I make a list of these objects

List <super> myList = new List<super>();
myList.Add(new super());
myList.Add(new sub());

Now I try to get each object in the list to query itself to see if it is a super-class or a sub-class

foreach(super objInList in myList)
{
  if(objInList.isSuper())
    Debug.Print("Super");
  else
    Debug.Print("Sub");
}

So what happens is that since each object is cast as a super-class, it uses the super-class method of isSuper() and it always responds as a super-class.

I want to access the sub-classes' isSuper() without having to use an instanceof in every single iteration of the loop. Obviously if you can query the object to see if it is a super or a sub, then something in the O/S knows the type of object. Why go through a guessing game of checking each possibility? Why not ask it to drill down to the appropriate sub-class and execute the appropriate method? Is there a way to achieve this goal?

st4hoo
  • 2,196
  • 17
  • 25
user3533030
  • 359
  • 3
  • 17
  • 2
    Unlike Java, you have to explicitly declare members as virtual and explicitly override them (using the override keyword) in C#. – Mike Zboray May 29 '14 at 08:12
  • 2
    Side note: if you are planning to copy/pasting Java samples as C# (which you did based on coding convention) it may be good idea to check on Java vs. C# differences... Like numeric types or default virtual behavior. – Alexei Levenkov May 29 '14 at 08:19
  • 1
    Also it helps to pay attention to compiler warnings, especially when your code doesn't work as you expect. In this case it warns you that you are hiding the isSuper method. – Mike Zboray May 29 '14 at 08:20

1 Answers1

9

You have to override super class property in your sub class to get required behaviuor.

Change your class definitions accordingly:

public class super
{ 
  public virtual Boolean isSuper()
  {
    return true;
  }
}

public class sub : super
{ 
  public override Boolean isSuper()
  {
    return false;
  }
}
st4hoo
  • 2,196
  • 17
  • 25
  • I would even suggest to make the code more idiomatic to C#: `public virtual bool IsBase { get { return true; } }` etc. – Shlomi Borovitz May 29 '14 at 08:18
  • Wow... it is that easy? Then why did the compiler allow it to compile? It makes no sense without an explicit override. – user3533030 May 29 '14 at 08:19
  • 2
    @user3533030 because [hiding/shadowing](http://stackoverflow.com/questions/392721/difference-between-shadowing-and-overriding-in-c) is not an error, but warning (consider changing "treat warnings as errors" for all your projects...) – Alexei Levenkov May 29 '14 at 08:21
  • 1
    @user3533030 - It does make sense in some cases, and the compiler did issued a warning that you should override the method, or mark it with `new` to make it hide (but not override) the base method: `public class Sub : Super { new public bool IsSuper() { ... } }` – Shlomi Borovitz May 29 '14 at 08:22
  • 1
    @user3533030 C# has been carefully designed to avoid the brittle base class problem. That is what not producing an error does. – Mike Zboray May 29 '14 at 08:22
  • @user3533030 You should have got a compiler warning. And like Alexei says, "Warning as errors" for the win. :) – Matthew Watson May 29 '14 at 08:22