Hiding And Overriding in C#

In this article we will talk about polymorphism in C# and look into the use of hiding and overriding.

Getting started

A developer who uses C# is expected to know what polymorphism is. In case someone is not sure, in a few words, polymorphism is the ability to treat a class, through inheritance, as if being of another type. Assume we create a class (which we will call derived class) in our application and this class inherits another class (base class). Our class can use the base class' parameters and methods as it inherits that class. Now, assume a method declared in the base class is re-declared in our class and we call this method through an object we have created. This method can refer to more than one classes depending on our code. Let's sort things out using a few examples.

class Parent

//Base class

{

public string GetCallName()

{

return "Called By Parent";

}

}

private string GetParentName()

{

//Gets base class method

Parent father = new Parent();

return father.GetCallName();

}

Using a base class object will obviously return "Called By Parent".

Now we will create the class EmptyChild that will inherit Parent but do nothing more than that.

class EmptyChild : Parent

//Inherits all Parent elements

{

}

public string GetEmptyChildName()

{

//Gets base class method

EmptyChild son = new EmptyChild();

return son.GetCallName();

}

The derived class has no reference to the base method. As a result, the method will use the base method and return "Called By Parent".

Hiding

Next step is to add this method. This way we will try to replace the base method with a new one. This is called hiding.

class Child : Parent

//Hides GetCallName from Parent class

{

public string GetCallName()

{

return "Called By Child";

}

}

private string GetChildName()

{

//Gets derived class method

Child son = new Child();

return son.GetCallName();

}

However the compiler will not like that we are trying to hide the base class that way and will ask as to use the "new" keyword. That is a way the compiler is trying to tell us that we are hiding a base method. It will make no actual difference whether we use the "new" keyword or not, but it will make our code look better and ensure that we have checked this warning next time we or another person walk by this line. So let's use this method instead.

class Child : Parent

//Hides GetCallName from Parent class

{

new public string GetCallName()

{

return "Called By Child";

}

}

Either way, we have now hidden the base class and the result will be "Called By Child".

Overriding

Supposing we used the next piece of code

private string GetParentNameNoOverride()

{

//Gets base class method as we are not using the override keyword

Parent father = new Parent();

father = new Child();

return father.GetCallName();

}

The result would be "Called By Parent". That's not surprising, as father is a Parent object. However there may be times when, after storing a derived class object into a base class object, we want to call the derived class' methods. In this case we will use the keywords "virtual" and "override". The base class method will be stated as virtual and the derived as override. The previous example needs to be formed as follows.

class VirtualParent

// Base class with virtual method

{

public virtual string GetCallName()

{

return "Called By VirtualParent";

}

}

class OverrideChild : VirtualParent

//Overrides GetCallName method

{

public override string GetCallName()

{

return "Called By OverrideChild";

}

}

private string GetParentNameOverride()

{

//Gets derived class method as we are using the override keyword

VirtualParent father = new VirtualParent();

father = new OverrideChild();

return father.GetCallName();

}

Overriding the method, we get "Called By OverrideChild". The method will no longer call the base class method. Next, we' ll try the opposite. Calling the base class through a derived class.

private string GetParentNameWithCasting()

{

//Will call base method

Child son = new Child();

return ((Parent)son).GetCallName();

}

This is based on the first example where Child class is hiding the Father's method. The result would be "Called By Parent". If however we used override

private string GetVirtualParentNameWithCasting()

{

//Will call derived method

OverrideChild son = new OverrideChild();

return ((VirtualParent)son).GetCallName();

}

we would get "Called By OverrideChild" as the derived class overrides the base class' method. The base class can no longer be called this way.

Base

To access an overriden class method we have to use the keyword "base", when the derived method declares the method. Let's create a new class.

This method returns "Called By VirtualParent". Why is that? ((VirtualParent)son).GetCallName() calls OverrideBaseChild.GetCallName() and this calls VirtualParent.GetCallName() returning "Called By Parent".

Sealing

We can go on inheriting class after class, using the override keyword each time, and we will always get the last derived class method. Ok, enough with overriding. We now want to go back to the original featuring and to do this we create the GrandChild class.

class GrandChild : OverrideChild

//Inherits overriden GetCallName method

{

new public string GetCallName()

{

return "Called By GrandChild";

}

}

private string GetGrandChildName()

{

//Gets override child class method as this is the last overriden method used

VirtualParent father = new VirtualParent();

father = new GrandChild();

return father.GetCallName();

}

The result would be "Called By OverrideChild". This was the last class we used the override method and that's why our result called that class method.

If we are 100% sure that our method will not use the overriding feature anymore we can use the "sealed" keyword. Using sealed, we have to stop the overriding sequence.

class SealedGrandChild : OverrideChild

//Inherits overriden GetCallName method

{

public sealed override string GetCallName()

{

return "Called By SealedGrandChild";

}

}

private string GetSealedGrandChildName()

{

//Gets derived class method as we are using the override keyword

VirtualParent father = new VirtualParent();

father = new SealedGrandChild();

return father.GetCallName();

}

In SealedGrandChild we create the sealed method. The result will be "Called By SealedGrandChild" as usual. However the next class that inherits SealedGrandChild works different.

class Descendant : SealedGrandChild

//Inherits SealedGrandChild; has new GetCallName method

{

public new string GetCallName()

{

return "Called By Descendant";

}

}

private string GetDescendantName()

{

//Gets sealed class method

VirtualParent father = new VirtualParent();

father = new Descendant();

return father.GetCallName();

}

The result would be "Called By SealedGrandChild" too, likewise when we used GrandChild class. Now, what would happen if we tried to override a sealed method?

class DescendantError : SealedGrandChild

//Inherits SealedGrandChild; Tries to override sealed method

{

public override string GetCallName()

{

return "Called By Descendant";

}

}

We would get an error stating "DescendantError.GetCallName()': cannot override inherited member 'SealedGrandChild.GetCallName()'" because it is sealed. Our method is sealed and we can no longer override it, like we mentioned earlier.

Conclusion

There are lot of ways to pick the method you want to call using polymorphism. Hiding and overriding are helpful resources you can use. You can end an overriding sequence using a sealed method.