If you have a base class
public abstract class AbsHashtableish<TKey, TValue>
{
public abstract TKey ConvertToKey(string key);
public abstract bool KeyExists(TKey key);
public virtual bool KeyExists(string key)
{
Console.WriteLine("In Base");
return KeyExists(ConvertToKey(key));
}
}
and a concerete class
public class ConcreteHashtableish: AbsHashtableish<string, Dinosaur>
{
...
public override string ConvertToKey(string key)
{
return key;
}
public override bool KeyExists(string key)
{
Console.WriteLine("In Sub");
return _list.Contains(key);
}
}
and client A
AbsHashtableish<string, Dinosaur> concreteA = new ConcreteHashtableish<string, Dinosaur>();
and client B
ConcreteHashtableish<string, Dinosaur> concreteB = new ConcreteHashtableish<string, Dinosaur>();
What are the rules (and if possible, the reasoning behind them) for determining whether the code shown above is sufficient to compile and if so:
KeyExists
on concreteA
vs concreteB
?KeyExists(string key)
, will we be able to get out of it?For question #2, what I mean is that if somehow the compiler is able to compile this code, does it do so by effectively hiding the base method from the client - because if that code was reached, it would result in an infinite loop?
Calling KeyExists
on both convreteA
and concreteB
is eventually the same.
The Common Language Runtime (CLR)
knows to invoke methods on the actual type (using a Virtual Method Table). This is the whole point of Polymorphism. It allows you to refer concrete implementations as abstract ones, but the actual methods getting called are of the concrete types.
In the particular example you gave, you can't use the base class implementation of KeyExists
from outside the derived class, simply because you can't create an instance of an abstract class. If it wasn't abstract, you can create:
AbsHashtableish<string, Dinosaur> baseA = new AbsHashtableish<string, Dinosaur>();
And AbsHashtableish.KeyExists
will get called.
EDIT: (Thanks to Oliver for noting)
You can always call the base class implementation from inside a derived class. In this case you would call:
base.KeyExists(key)