I dont need to use atributes override and virtual when I change code of a method of the same name in a inherited class. Why is that?

Viewed 35

Im trying to learn Csharp on my own. I read that if I want to change the code of the method textmethod in inherited class Class2, I have to write override in front of the method in Class2 and virtual in front of the method in base Class1. So I thought that the textmethod below wont work or change without these atributes. But the method still got updated and I get the text of Class2 textmethod if I make instance of Class2, and exactly the same thing happens when I use the override/virtual atributes. Im using .Net 6.0. What am I missing?

namespace nn
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Class2 class2 = new Class2();
            class2.textmethod();
            Console.ReadKey();
        }
    }

    public class Class1 
    {
        public  void textmethod()
        {
            Console.WriteLine("hello");
        }
    }

    public class Class2 : Class1
    {
        public void textmethod()
        {
            Console.WriteLine("hello there");
        }
    }
}
1 Answers

As hinted at by Jon Skeet your question boils down to the difference between the override and new keywords.

Let's see what the official documentation has to say about that:

In C#, a method in a derived class can have the same name as a method in the base class. You can specify how the methods interact by using the new and override keywords. The override modifier extends the base class virtual method, and the new modifier hides an accessible base class method.

You might wonder where the new might come from as you didn't use that keyword in your method declaration. However the compiler will implicitly have added it for you. Doing so it will also have notified you about it with a compiler warning to explicitly use the new keyword.

So what's the difference?

When using the same method signature in a child class as in the parent class without specifically using override you implicitly create a new method with the same name in the child class that hides the method it inherits from it's parent class. You therefore end up with two different methods with the same name and signature. One in Class1 and one in Class2 and depending on what Type your instance is at runtime it will choose which method to execute. What this means is that when using the following code:

Class2 class2 = new Class2();
class2.textmethod();

it executes the method specified in Class2 (as it hides the other textmethod() that is declared in Class1). However if you were to change your code as follows (notice how we use poly morphism to assign the Class2 insatance to a variable of type Class1):

Class1 class2 = new Class2();
class2.textmethod();

in this case the original textmethod() as declared in Class1 would be executed. Even though your class2 object is still of type Class2 the hidden base method in Class1 will be executed.

This is where override is different. Instead of creating a second textmethod() on Class2 it overrides (literally replaces / extends) the method declared in Class1. This means it doesn't matter if you cast your Class2 instance to Class1 or not, in either way the textmethod() declared in Class2 would be executed.

I highly suggest you take a look at the documentation linked above. There are more examples like that which help a lot when diving into the subtle differences of inheritance in c# :)

Related