Override vs New behavior

A look into polymorphism with override and new and their differing behavior

Home DailyDrop

Daily Knowledge Drop

When using polymorphism, even though on the surface they appear to be doing the same thing, hiding the functionality of a parent, the override and new keywords behave very differently.

Override will hide the parent method invoked, and the overridden method on the child will be called. However when new is used on a method, when invoked, the parent method will be called.


Definition recap

A lot of keywords used in the introduction above, so a quick recap on some of the definitions of the keywords.

Polymorphism

Polymorphism allows for objects of a derived class can be treated as objects of the parent class.

For example, when a Child class inherits from a Parent class, then the following is valid:

// defined as type Parent
// but assigned a Child
Parent childEntity = new Child();

Virtual

Often the Parent class will defined methods as virtual (which can also be applied to properties, indexers), which allows for it to be explicitly overridden in the Child class.

public class Parent
{
    public virtual void Hello()
    {
        Console.WriteLine("Hello, I am Parent");
    }
}

Override

The override keyword is used on a Child class, to override the behavior defined by the Parent class:

public class Child : Parent
{
    // Override the Parent Hello method
    public override void Hello()
    {
        Console.WriteLine("Hello, I am Child");
    }
}

New

The new keyword can be used as a declaration modifier to explicitly hide the base class functionality:

public class Child : Parent
{
    // Hide the Parent Hello method
    public new void Hello()
    {
        Console.WriteLine("Hello, I am Child");
    }
}

New vs override

There is a subtle difference between the definitions of the override and new keywords:

  • override will override the parent method
  • new will hide the parent method

What all this comes down to, is the following - consider a Parent and two different Child classes, one using new and one using override:

public class Parent
{
    public virtual string Ping()
    {
        return $"Response from {nameof(Parent)}";
    }
}

public class OverrideChild : Parent
{
    public override string Ping()
    {
        return $"Response from {nameof(OverrideChild)}";
    }
}

public class NewChild : Parent
{
    public new string Ping()
    {
        return $"Response from {nameof(NewChild)}";
    }
}

When we declare an instance of each of the three types and call the Ping method, we get a response from the method on the respective type:

Parent parent = new Parent();
NewChild newChild = new NewChild();
OverrideChild overChild = new OverrideChild();

Console.WriteLine(parent.Ping());
Console.WriteLine(newChild.Ping());
Console.WriteLine(overChild.Ping());

The resulting output being:

Response from Parent
Response from NewChild
Response from OverrideChild

So far, so good - all is as expected.


Polymorphism

However, when using polymorphism then behavior starts to change.

In the below, each type is declare of type Parent by assigned one of the three different types (this is allowed, because of polymorphism):

// all type Parent
// but assigned different types
Parent parent = new Parent();
Parent overChild = new OverrideChild();
Parent newChild = new NewChild();

Console.WriteLine(parent.Ping()); 
Console.WriteLine(overChild.Ping()); 
Console.WriteLine(newChild.Ping()); 

Now the output is as follows:

Response from Parent
Response from OverrideChild
Response from Parent

From this we can see that with:

  • override: there is a link between the child and parent entities, so when the method is called the runtime knows to call the child entity method (even though the type is Parent)
  • new: the parent method is hidden by the child method, but there is no link between them, so calling the method on a Parent entity (even though it was assigned a Child) will call the parent entity method

Notes

Interesting behavior from the runtime which one should be aware of, otherwise unexpended results might occur. There is no right or wrong modifier to use, it will depend on the use case, how the classes are defined and used, and how they should behave.


References

Override vs New Polymorphism In C# .NET


Daily Drop 144: 23-08-2022

At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.

The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.
c# .net new virtual polymorphism