C# Virtual Override

  • The virtual keyword tells the compiler that the member with virtual modifier can be overridden in the derived classes.
  • The virtual keyword can be used in a method, property, indexer or event declaration. In this section, we'll introduced virtual methods only.
  • The override method in the derived class is used to override the method of virtual, abstract or override in the base class with the same signature.
  • In a inheritance hierarchy, the overriding method in the most derived class will be invoked eventually if the virtual method is called in a derived class.
  • The virtual keyword cannot be used with static, abstract, private or override keyword together on a class member.
  • The virtual method and its override methods must be in the same access level or have the same access modifier.

The following example was changed from the example of name hiding 01-55-02

Example 01-56-01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;

namespace TestVirtualOverride
{
    public class A
    {
        public int i = 1;
        public int j = 2;

        public virtual void test()
        {
            Console.WriteLine("A class");
        }
    }

    public class B : A
    {
        new public int j = 3;     // Add new here

        public override void test()    // Add new here
        {
            Console.WriteLine("B class");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            Console.WriteLine("i={0}, j={1}", a.i, a.j);    // Output i=1, j=2
            a.test();                                       // Output A class
            B b = new B();
            Console.WriteLine("i={0}, j={1}", b.i, b.j);    // Output i=1, j=3
            b.test();                                       // Output B class
            Console.Read();
        }
    }
}

Output

i=1, j=2
A class
i=1, j=3
B class

Explanation

  • Line 10: Define a virtual method test() in class A.
  • Line 20: Define an override method test() in class B to override the method in line 10.

You can see we got the same results of Example 01-55-02 and Example 01-56-01. So the next, we'll give you an example to distinguish the difference between the method overriding and method hiding.

Any objects of a derived class can be assigned to the base class type instead of the derived class type. This is called Polymorphism which will be introduced later.

For example, Class B is a derived class of class A. We can create an instance of the class B and assign it to Class A type.

A a = new B();

But the following is not allowed.

B b = new A();

It's something like you can convert a int-typed data to a long-typed data implicitly but you cannot do it reversely.

Assume class C is a derived class of class B, the following declarations are all legal.

C c = new C();
B b = new C();
A a = new C();

Now we can describe the difference between Method Overriding and Method Hiding in the following example.

Example 01-56-02

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;

namespace TestVirtualOverride
{
    public class A
    {
        public virtual void test1()
        {
            Console.WriteLine("Test 1 in A class");
        }

        public void test2()
        {
            Console.WriteLine("Test 2 in A class");
        }
    }

    public class B : A
    {
        public override void test1()
        {
            Console.WriteLine("Test 1 in B class");
        }

        new public void test2()
        {
            Console.WriteLine("Test 2 in B class");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new B();
            a.test1();    // Test 1 in B class
            a.test2();    // Test 2 in A class
            B b = (B) a;
            b.test1();    // Test 1 in B class
            b.test2();    // Test 2 in B class
            Console.Read();
        }
    }
}

Output

Test 1 in B class
Test 2 in A class
Test 1 in B class
Test 2 in B class

Explanation

  • Line 5-16: Define the class A with one virtual method test1() and a normal method test2().
  • Line 18-29: Define the derived class B inheriting from class A.
  • Line 20-23: Define the overriding method test1() with the keyword override in class B.
  • Line 25-28: Define a new method test2() to hide the method with the same name in class A.
  • Line 31-43: Testing class Program.
  • Line 33-42: Main method.
  • Line 35: Create an instance of B and assign it to class A.
  • Line 36: Call the method test1 of class A. However, this is a virtual method and the overriding method in the most derived class will be invoked. The a hosts the instance of class B at run time so the method in class B will be invoked instead of that in class A.
  • Line 37: Call the method test2 of class A. This method is not a virtual method so the method test2() in class A will be invoked and output "Test 2 in A class".
  • Line 38: A cast is needed to explicitly convert an instance from a base class type to a derived class type. There is no run time error in the code because a is actually holding the instance of class B.
  • Line 39: The method test1() in class B is invoked.
  • Line 40: The method test2() in class B is invoked because it hides the method in class A and runs as a new method.