It's not really overriding it, it's shadowing it. Given a reference to a Derived
object, Base
's HelpMeNow
function will not be accessible1, and derivedObject.HelpMeNow()
will call Derived
's implementation.
This is not the same as overriding a virtual function, which HelpMeNow
is not. If a Derived
object is stored in a reference to a Base
, or to an IHelper
, then Base
's HelpMeNow()
will be called, and Derived
's implementation will be inaccessible.
Derived derivedReference = new Derived();
Base baseReference = derivedReference;
IHelper helperReference = derivedReference;
derivedReference.HelpMeNow(); // outputs "Derived.HelpMeNow()"
baseReference.HelpMeNow(); // outputs "Base.HelpMeNow()"
helperReference.HelpMeNow(); // outputs "Base.HelpMeNow()"
Of course, if the above is not the desired behavior, and it's usually not, there are two possibilities. If you control Base
, simply change HelpMeNow()
to virtual, and override it in Derived
instead of shadowing it. If you don't control Base
, then you can at least fix it halfway, by reimplementing IHelper
, like so:
class Derived : Base, IHelper{
public new void HelpMeNow(){Console.WriteLine("Derived.HelpMeNow()");}
void IHelper.HelpMeNow(){HelpMeNow();}
}
This version of Derived
uses what's called explicit interface implementation, which allows you to satisfy the contract of implementing an interface without adding the implementation to your class's public interface. In this example, we already have an implementation in Derived
's public interface that's inherited from Base
, so we have to explicitly implement IHelper
to change it2. In this example, we just forward the implementation of IHelper.HelpMeNow
to our public interface, which is the shadow of Base
's.
So with this change, a call to baseReference.HelpMeNow()
still outputs "Base.HelpMeNow()", but a call to helperReference.HelpMeNow()
will now output "Derived.HelpMeNow()". Not as good as changing Base
's implementation to virtual, but as good as we're gonna get if we don't control Base
.
1Exception: it is accessible from within methods of Derived
, but only when qualified with base.
, as in base.HelpMeNow()
.
2Notice that we also have to declare IHelper
as an interface the class implements, even though we inherit this declaration from Base
.