273

Wondering what the difference is between the following:

Case 1: Base Class

public void DoIt();

Case 1: Inherited class

public new void DoIt();

Case 2: Base Class

public virtual void DoIt();

Case 2: Inherited class

public override void DoIt();

Both case 1 and 2 appear to have the same effect based on the tests I have run. Is there a difference, or a preferred way?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • 3
    Duplicate of many questions, including http://stackoverflow.com/questions/159978/c-keyword-usage-virtualoverride-vs-new – Jon Skeet Sep 09 '09 at 11:46

14 Answers14

348

The override modifier may be used on virtual methods and must be used on abstract methods. This indicates for the compiler to use the last defined implementation of a method. Even if the method is called on a reference to the base class it will use the implementation overriding it.

public class Base
{
    public virtual void DoIt()
    {
    }
}

public class Derived : Base
{
    public override void DoIt()
    {
    }
}

Base b = new Derived();
b.DoIt();                      // Calls Derived.DoIt

will call Derived.DoIt if that overrides Base.DoIt.

The new modifier instructs the compiler to use your child class implementation instead of the parent class implementation. Any code that is not referencing your class but the parent class will use the parent class implementation.

public class Base
{
    public virtual void DoIt()
    {
    }
}

public class Derived : Base
{
    public new void DoIt()
    {
    }
}

Base b = new Derived();
Derived d = new Derived();

b.DoIt();                      // Calls Base.DoIt
d.DoIt();                      // Calls Derived.DoIt

Will first call Base.DoIt, then Derived.DoIt. They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.

Source: Microsoft blog

Callum Watkins
  • 2,844
  • 4
  • 29
  • 49
rahul
  • 184,426
  • 49
  • 232
  • 263
  • 8
    `This indicates for the compiler to use the last defined implementation of a method`. how can find last defined implementation of a method?? – AminM Mar 05 '14 at 19:30
  • 8
    Start from a concrete class, check whether it has an implementation of the method of interest. If it does, you're done. If it doesn't, go one step up in the inheritance hierarchy, i.e., check whether the super class has the method of interest. Continue until you have found the method of interest. – csoltenborn Oct 24 '14 at 08:16
  • 5
    Also note that you can only `override` a method when the base class defines the method as `virtual`. The word `virtual` is the base class saying "Hey, when I call this method, it could have virtually been replaced by a derived implementation, so I don't really know in advance what method implementation I'm actually calling at runtime. So `virtual` signifies is a placeholder for a method. This implies that methods that are not marked as `virtual` can not be overridden. But you can _replace_ any non-virtual method in a derived class with the modifier `new`, only accessible at derived level. – Erik Bongers May 20 '18 at 10:03
  • 1
    what if you literally call `base.DoIt()` inside the Derived class? – Joe Phillips Aug 09 '21 at 18:00
204

virtual: indicates that a method may be overriden by an inheritor

override: overrides the functionality of a virtual method in a base class, providing different functionality.

new: hides the original method (which doesn't have to be virtual), providing different functionality. This should only be used where it is absolutely necessary.

When you hide a method, you can still access the original method by up casting to the base class. This is useful in some scenarios, but dangerous.

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
Jon B
  • 51,025
  • 31
  • 133
  • 161
21

In the first case you are hiding the definition in the parent class. This means that it will only be invoked when you are dealing with the object as the child class. If you cast the class to its parent type, the parent's method will be invoked. In the second instance, the method is overridden and will be invoked regardless of whether the object is cast as the child or parent class.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
11
  • new means respect your REFERENCE type(left-hand side of =) , thereby running reference types's method. If redefined method doesn't have new keyword, it is behaved as it has. Moreover, it also known as non-polymorphic inheritance. That is, “I’m making a brand new method in the derived class that has absolutely nothing to do with any methods by the same name in the base class.” - by said Whitaker
  • override, which must be used with virtual keyword in its base class, means respect your OBJECT type(right-hand side of =), thereby running method overriden in regardless of reference type. Moreover, it also known as polymorphic inheritance.

My way to bear in mind both keywords that they are opposite of each other.

override: virtual keyword must be defined to override the method. The method using override keyword that regardless of reference type(reference of base class or derived class) if it is instantiated with base class, the method of base class runs. Otherwise, the method of derived class runs.

new: if the keyword is used by a method, unlike override keyword, the reference type is important. If it is instantiated with derived class and the reference type is base class, the method of base class runs. If it is instantiated with derived class and the reference type is derived class, the method of derived class runs. Namely, it is contrast of override keyword. En passant, if you forget or omit to add new keyword to the method, the compiler behaves by default as new keyword is used.

class A 
{
    public string Foo() 
    {
        return "A";
    }

    public virtual string Test()
    {
        return "base test";
    }
}

class B: A
{
    public new string Foo() 
    {
        return "B";
    }
}

class C: B 
{
    public string Foo() 
    {
        return "C";
    }

    public override string Test() {
        return "derived test";
    }
}

Call in main:

A AClass = new B();
Console.WriteLine(AClass.Foo());
B BClass = new B();
Console.WriteLine(BClass.Foo());
B BClassWithC = new C();
Console.WriteLine(BClassWithC.Foo());

Console.WriteLine(AClass.Test());
Console.WriteLine(BClassWithC.Test());

Output:

A
B
B
base test
derived test

New code example,

Play with code by commenting in one-by-one.

class X
{
    protected internal /*virtual*/ void Method()
    {
        WriteLine("X");
    }
}
class Y : X
{
    protected internal /*override*/ void Method()
    {
        base.Method();
        WriteLine("Y");
    }
}
class Z : Y
{
    protected internal /*override*/ void Method()
    {
        base.Method();
        WriteLine("Z");
    }
}

class Programxyz
{
    private static void Main(string[] args)
    {
        X v = new Z();
        //Y v = new Z();
        //Z v = new Z();
        v.Method();
}
  • "Override is with respect to the right-hand of assignment, new is with respect to the left-hand of assignment". Good way of remembering this, thanks! – Ferazhu Jun 15 '21 at 12:17
10

enter image description here

All combinations of none, virtual, override, new and abstract:

Victor Stagurov
  • 4,566
  • 1
  • 15
  • 15
  • 4
    This table deserves more love. It's more helpful as a reminder than the many pages of the official documentation that covers this topic. – ScienceSnake Aug 12 '22 at 13:25
8

try following: (case1)

((BaseClass)(new InheritedClass())).DoIt()

Edit: virtual+override are resolved at runtime (so override really overrides virtual methods), while new just create new method with the same name, and hides the old, it is resolved at compile time -> your compiler will call the method it 'sees'

nothrow
  • 15,882
  • 9
  • 57
  • 104
4

The difference between the two cases is that in case 1, the base DoIt method does not get overridden, just hidden. What this means is that depending on the type of the variable depends on which method will get called. For example:

BaseClass instance1 = new SubClass();
instance1.DoIt(); // Calls base class DoIt method

SubClass instance2 = new SubClass();
instance2.DoIt(); // Calls sub class DoIt method

This can be really confusing and results in non expected behaviour and should be avoided if possible. So the preferred way would be case 2.

Christian Specht
  • 35,843
  • 15
  • 128
  • 182
Shannon Cornish
  • 961
  • 5
  • 11
4

In case 1 if you used call the DoIt() method of the inherited class while the type is declared as the base class you will see the action of the base class even.

/* Results
Class1
Base1
Class2
Class2
*/
public abstract class Base1
{
    public void DoIt() { Console.WriteLine("Base1"); }
}
public  class Class1 : Base1 
{
    public new void DoIt() { Console.WriteLine("Class1"); }
}
public abstract class Base2
{
    public virtual void DoIt() { Console.WriteLine("Base2"); }
}
public class Class2 : Base2
{
    public override void DoIt() { Console.WriteLine("Class2"); }
}
static void Main(string[] args)
{
    var c1 = new Class1();
    c1.DoIt();
    ((Base1)c1).DoIt();

    var c2 = new Class2();
    c2.DoIt();
    ((Base2)c2).DoIt();
    Console.Read();
}
Matthew Whited
  • 22,160
  • 4
  • 52
  • 69
3

I had the same question and it's really confusing, you should consider that override and new keywords working only with objects of type base class and value of derived class. In this case only you'll see the effect of override and new: So if you have class A and B, B inherits from A, then you instantiate an object like this:

A a = new B();

Now on calling methods will take its state into consideration. Override: means that it extends the function of the method, then it uses the method in the derived class, whereas new tell the compiler to hide the method in the derived class and use the method in the base class instead. Here is a very good sight to that subject:

https://msdn.microsoft.com/EN-US/library/ms173153%28v=VS.140,d=hv.2%29.aspx?f=255&MSPPError=-2147217396

3

The article below is in vb.net but I think the explanation about new vs overrides is very easy to grasp.

https://www.codeproject.com/articles/17477/the-dark-shadow-of-overrides

At some point in the article, there is this sentence:

In general, Shadows assumes the function associated with the type is invoked, while Overrides assumes the object implementation is executed.

The accepted answer to this question is perfect but I think this article provide good examples to add better meaning about the differences between these two keywords.

Samuel
  • 12,073
  • 5
  • 49
  • 71
2

If keyword override is used in derive class then its override the parent method.

If Keyword new is used in derive class then derive method hided by parent method.

Sangram Nandkhile
  • 17,634
  • 19
  • 82
  • 116
saba
  • 43
  • 7
1

Out of all those, new is the most confusing. Through experimenting, the new keyword is like giving developers the option to override the inheriting class implementation with the base class implementation by explicitly defining the type. It is like thinking the other way around.

In the example below, the result will return "Derived result" until the type is explicitly defined as BaseClass test, only then "Base result" will be returned.

class Program
{
    static void Main(string[] args)
    {
        var test = new DerivedClass();
        var result = test.DoSomething();
    }
}

class BaseClass
{
    public virtual string DoSomething()
    {
        return "Base result";
    }
}

class DerivedClass : BaseClass
{
    public new string DoSomething()
    {
        return "Derived result";
    }
}
usefulBee
  • 9,250
  • 10
  • 51
  • 89
0

The functional difference will not be show in these tests:

BaseClass bc = new BaseClass();

bc.DoIt();

DerivedClass dc = new DerivedClass();

dc.ShowIt();

In this exmample, the Doit that is called is the one you expect to be called.

In order to see the difference you have to do this:

BaseClass obj = new DerivedClass();

obj.DoIt();

You will see if you run that test that in the case 1 (as you defined it), the DoIt() in BaseClass is called, in case 2 (as you defined it), the DoIt() in DerivedClass is called.

Ken Falk
  • 26
  • 2
0

new : It just hides the method of the base class, but you can access it if you want.

override: It's overriding the base class's method and you can't access it even if you want to.

Example

using System;

public class Program
{
    public static void Main()
    {
        BaseClass test = new DerivedClass();
        var result = test.DoSomething();
        
        Console.WriteLine(result);
    }

    class BaseClass
    {
        public string DoSomething()
        {
            return "Base result";
        }
    }

    class DerivedClass : BaseClass
    {
        public new string DoSomething()
        {
            return "Derived result";
        }
    }
}

Result: Base result

P.S. I copied and slightly changed the above example from the following link: https://stackoverflow.com/a/45822233/10995103

ilyas varol
  • 788
  • 3
  • 10
  • 25