This is a interview question. So is it possible to override a method without virtual specified in parent method?
views:
93answers:
6The "new" keyword can hide a method defined in a base class when you access that method through a compile-time reference of type T such that typeof(DerivedClass).IsAssignableFrom(typeof(T)). You can not truly override it, however. References that use the base type at compile time will always call the base method regardless of what you do in the definition of the derived class.
If I were asked that question in an interview, that's what I would say. If I were asking it, that's the answer I'd hope for. Anyone who thinks that "new" is the same as "override" and doesn't qualify their answer somehow doesn't understand what "virtual" means or how vtables work (conceptually or mechanically).
Technically you cannot override the method. You can hide it, though, using the new
keyword:
class Foo
{
public void Bar() {}
}
class FooChild : Foo
{
new public void Bar() {}
}
The catch is that when you call Bar()
from the base class (or if you cast FooChild to Foo), it will execute the base class' code - not the "new" code.
They probably wanted you to say "Use the new
keyword to hide the method." Which technically does not override the method. If you have
class Base
{
public void Bar() { Console.WriteLine("Base"); }
}
class Derived : Base
{
public new void Bar() { Console.WriteLine("Derived"); }
}
And then you wrote
Derived derived = new Derived();
derived.Bar();
((Base)derived).Bar();
You would see different results. So functions that use the base class would get the results for the base method, and functions that use the derived class would get the results for the new method.
If overriding non-virtual public methods was possible, we would have much more powerful mocking frameworks. No, it's not possible to override non-virtual members, only hide them using new
keyword.
The following is not overriding. Also, please never do this for real. It's a "trick" to provide an alternative behaviour, though:
class Base
{
protected Action m_action;
public Base()
{
m_action = () => Console.WriteLine("Base Class");
}
public void NonVirtual()
{
m_action();
}
}
class Derived : Base
{
public Derived()
{
m_action = () => Console.WriteLine("Derived Class");
}
}
class Program
{
static void Main (string[] args)
{
Base baseClass = new Base();
Derived derivedClass = new Derived();
Base derivedAsBase = derivedClass;
Console.WriteLine("Calling Base:");
baseClass.NonVirtual();
Console.WriteLine("Calling Derived:");
derivedClass.NonVirtual();
Console.WriteLine("Calling Derived as Base:");
derivedAsBase.NonVirtual();
Console.ReadKey();
}
}
Result:
Calling Base:
Base Class
Calling Derived:
Derived Class
Calling Derived as Base:
Derived Class
Edit: Although I say it's a trick, it could be tidied up into the Strategy pattern or similar.