Saturday, February 27, 2016

OOPS : Virtual, Override and New keyword in C#

Understanding virtual, override and new keyword in C#

Polymorphism is the concepts of OOPS which includes method overriding and method overloading. Virtual and Override keyword are used for method overriding and new keyword is used for method hiding. Let's have look on these keywords in C# and try to understand each importance.
Simple Class Inheritance
Consider the below class hierarchy with classes A, B and C. A is the super/base class, B is derived from class A and C is derived from class B.

Class A   ------>   Class B  ------->  Class C
Test()                      Test()                  Test()


If a method Test() is declared in the base class A and classes B or C has no methods as shown below.
1.  using System;
2.  namespace Polymorphism
3.  {
4.   class A
5.   {
6.   public void Test() { Console.WriteLine("A::Test()"); }
7.   }
8.   
9.   class B : A { }
10.  
11.  class C : B { }
12.  
13.  class Program
14.  {
15.  static void Main(string[] args)
16.  {
17.  A a = new A();
18.  a.Test(); // output --> "A::Test()"
19.  
20.  B b = new B();
21.  b.Test(); // output --> "A::Test()"
22.  
23.  C c = new C();
24.  c.Test(); // output --> "A::Test()"
25.  
26.  Console.ReadKey();
27.  
28.  }
29.  }
30. }
Suppose you have Test() method in all the classes A, B, C as shown below:
1.  using System;
2.  namespace Polymorphism
3.  {
4.   class A
5.   {
6.   public void Test() { Console.WriteLine("A::Test()"); }
7.   }
8.   
9.   class B : A
10.  {
11.  public void Test() { Console.WriteLine("B::Test()"); }
12.  }
13.  
14.  class C : B
15.  {
16.  public void Test() { Console.WriteLine("C::Test()"); }
17.  }
18.  
19.  class Program
20.  {
21.  static void Main(string[] args)
22.  {
23.  
24.  A a = new A();
25.  B b = new B();
26.  C c = new C();
27.  
28.  a.Test(); // output --> "A::Test()"
29.  b.Test(); // output --> "B::Test()"
30.  c.Test(); // output --> "C::Test()"
31.  
32.  a = new B();
33.  a.Test(); // output --> "A::Test()"
34.  
35.  b = new C();
36.  b.Test(); // output --> "B::Test()"
37.  
38.  Console.ReadKey();
39.  }
40.  }
41. }
When you will run the above program, it will run successfully and gives the O/P. But this program will show the two warnings as shown below:
1.       'Polymorphism.B.Test()' hides inherited member 'Polymorphism.A.Test()'. Use the new keyword if hiding was intended.
2.       'Polymorphism.C.Test()' hides inherited member 'Polymorphism.B.Test()'. Use the new keyword if hiding was intended.
Method Hiding (new keyword)
As you have seen in the above example the compiler generate the warnings since C# also supports method hiding. For hiding the base class method from derived class simply declare the derived class method with new keyword. Hence above code can be re-written as :
1.  using System;
2.  namespace Polymorphism
3.  {
4.   class A
5.   {
6.   public void Test() { Console.WriteLine("A::Test()"); }
7.   }
8.   
9.   class B : A
10.  {
11.  public new void Test() { Console.WriteLine("B::Test()"); }
12.  }
13.  
14.  class C : B
15.  {
16.  public new void Test() { Console.WriteLine("C::Test()"); }
17.  }
18.  
19.  class Program
20.  {
21.  static void Main(string[] args)
22.  {
23.  
24.  A a = new A();
25.  B b = new B();
26.  C c = new C();
27.  
28.  a.Test(); // output --> "A::Test()"
29.  b.Test(); // output --> "B::Test()"
30.  c.Test(); // output --> "C::Test()"
31.  
32.  a = new B();
33.  a.Test(); // output --> "A::Test()"
34.  
35.  b = new C();
36.  b.Test(); // output --> "B::Test()"
37.  
38.  Console.ReadKey();
39.  }
40.  }
41. }
Moreover, if you are expecting the fourth and fifth output should be "B::Foo()" and "C::Foo()" since the objects a and b are referenced by the object of B and C respectively then you have to re-write the above code for Method Overriding.
Method Overriding (virtual and override keyword)
In C#, for overriding the base class method in derived class, you have to declare base class method as virtual and derived class method as override as shown below:
1.  using System;
2.  namespace Polymorphism
3.  {
4.   class A
5.   {
6.   public virtual void Test() { Console.WriteLine("A::Test()"); }
7.   }
8.   
9.   class B : A
10.  {
11.  public override void Test() { Console.WriteLine("B::Test()"); }
12.  }
13.  
14.  class C : B
15.  {
16.  public override void Test() { Console.WriteLine("C::Test()"); }
17.  }
18.  
19.  class Program
20.  {
21.  static void Main(string[] args)
22.  {
23.  
24.  A a = new A();
25.  B b = new B();
26.  C c = new C();
27.  a.Test(); // output --> "A::Test()"
28.  b.Test(); // output --> "B::Test()"
29.  c.Test(); // output --> "C::Test()"
30.  
31.  a = new B();
32.  a.Test(); // output --> "B::Test()"
33.  
34.  b = new C();
35.  b.Test(); // output --> "C::Test()"
36.  
37.  Console.ReadKey();
38.  }
39.  }
40. }
Mixing Method Overriding and Method Hiding
You can also mix the method hiding and method overriding by using virtual and new keyword since the method of a derived class can be virtual and new at the same time. This is required when you want to further override the derived class method into next level as I am overriding Class B, Test() method in Class C as shown below:
1.  using System;
2.  namespace Polymorphism
3.  {
4.   class A
5.   {
6.   public void Test() { Console.WriteLine("A::Test()"); }
7.   }
8.   
9.   class B : A
10.  {
11.  public new virtual void Test() { Console.WriteLine("B::Test()"); }
12.  }
13.  
14.  class C : B
15.  {
16.  public override void Test() { Console.WriteLine("C::Test()"); }
17.  }
18.  
19.  class Program
20.  {
21.  static void Main(string[] args)
22.  {
23.  
24.  A a = new A();
25.  B b = new B();
26.  C c = new C();
27.  
28.  a.Test(); // output --> "A::Test()"
29.  b.Test(); // output --> "B::Test()"
30.  c.Test(); // output --> "C::Test()"
31.  
32.  a = new B();
33.  a.Test(); // output --> "A::Test()"
34.  
35.  b = new C();
36.  b.Test(); // output --> "C::Test()"
37.  
38.  Console.ReadKey();
39.  }
40.  }
41. }
Note

1.       The virtual keyword is used to modify a method, property, indexer, or event declared in the base class and allow it to be overridden in the derived class.
2.       The override keyword is used to extend or modify a virtual/abstract method, property, indexer, or event of base class into derived class.
3.       The new keyword is used to hide a method, property, indexer, or event of base class into derived class.
-------------------------

Virtual Keyword
Virtual keyword is used for generating a virtual path for its derived classes on implementing method overriding. Virtual keyword is used within a set with override keyword. It is used as:
Hide   Copy Code
// Base Class
    class A
    {
        public virtual void show()
        {
            Console.WriteLine("Hello: Base Class!");
            Console.ReadLine();
        }
    }
Override Keyword
Override keyword is used in the derived class of the base class in order to override the base class method.Override keyword is used with virtual keyword, as:
Hide   Copy Code
// Base Class
    class A
    {
        public virtual void show()
        {
            Console.WriteLine("Hello: Base Class!");
            Console.ReadLine();
        }
    }

// Derived Class

    class B : A
    {
        public override void show()
        {
            Console.WriteLine("Hello: Derived Class!");
            Console.ReadLine();
        }
    }
New Keyword
New keyword is also used in polymorphism concept, but in the case of method overloading So what does overloading means, in simple words we can say procedure of hiding your base class through your derived class.
It is implemented as:
Hide   Copy Code
class A
    {
        public void show()
        {
            Console.WriteLine("Hello: Base Class!");
            Console.ReadLine();
        }
    }

    class B : A
    {
        public new void show()
        {
            Console.WriteLine("Hello: Derived Class!");
            Console.ReadLine();
        }
    }
Demo Example
Sample Implementation
Here’s a simple implementation in C# without using any keyword. Do you think it will run fine or show some RUN or COMPILE time errors?
Let’s see:
Hide   Shrink http://www.codeproject.com/images/arrow-up-16.png   Copy Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Generics
{
    class A
    {
        public void show()
        {
            Console.WriteLine("Hello: Base Class!");
            Console.ReadLine();
        }
    }

    class B : A
    {
        public void show()
        {
            Console.WriteLine("Hello: Derived Class!");
            Console.ReadLine();
        }
    }

    class Polymorphism
    {
        public static void Main()
        {
            A a1 = new A();
            a1.show();
            B b1 = new B();
            b1.show();
            A a2 = new B();
            a2.show();

        }
    }
}
Output Window



http://www.codeproject.com/KB/cs/816448/image001.jpg

It is showing some sort of output which means there is neither run time nor compile time error. But it will definitely show a Warning to you in your Visual Studio. So what is it and how to remove it. Do you want to know?
Keep reading and you will go through that.
Warning Message
Here’s a warning message that you will get:



http://www.codeproject.com/KB/cs/816448/image002.jpg
Solution
The solution of this problem is already in the warning. Just read it carefully and you will get that. Yes, you got that right, for removing that warning we need to use NEW keyword.
In the next sample, the demo example shows you a simple demo snippet and implementation of new keyword.
(I hope now you get why we are using new keyword in here.)
New Keyword | Method Overloading
Here’s a simple snippet of method overloading mechanism. So just go through it and guess the output:
Hide   Shrink http://www.codeproject.com/images/arrow-up-16.png   Copy Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Generics
{
    class A
    {
        public void show()
        {
            Console.WriteLine("Hello: Base Class!");
            Console.ReadLine();
        }
    }

    class B : A
    {
        public new void show()
        {
            Console.WriteLine("Hello: Derived Class!");
            Console.ReadLine();
        }
    }

    class Polymorphism
    {
        public static void Main()
        {
            A a1 = new A();
            a1.show();
            B b1 = new B();
            b1.show();
            A a2 = new B();
            a2.show();

        }
    }
}
Output Window



http://www.codeproject.com/KB/cs/816448/image001.jpg
Explanation
The procedure goes something like this:
(using overhiding as a ref for overloading)



http://www.codeproject.com/KB/cs/816448/image003.gif
Virtual & Override Keywords | Method Overriding
This is a simple example of method overriding. Just go through it and guess the output again and also try to differentiate between the previous snippet and this snippet.
Hide   Shrink http://www.codeproject.com/images/arrow-up-16.png   Copy Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Generics
{
    class A
    {
        public virtual void show()
        {
            Console.WriteLine("Hello: Base Class!");
            Console.ReadLine();
        }
    }

    class B : A
    {
        public override void show()
        {
            Console.WriteLine("Hello: Derived Class!");
            Console.ReadLine();
        }
    }

    class Polymorphism
    {
        public static void Main()
        {
            A a1 = new A();
            a1.show();
            B b1 = new B();
            b1.show();
            A a2 = new B();
            a2.show();
        }
    }
}
Output Window



http://www.codeproject.com/KB/cs/816448/image004.jpg
Explanation
The flow goes something like this:



http://www.codeproject.com/KB/cs/816448/image005.gif
Overriding + Hiding | Together
In this snippet, I show how both these methods can work together in the same snippet. So just go through this and guess the output.
Hide   Shrink http://www.codeproject.com/images/arrow-up-16.png   Copy Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Generics
{
    class A
    {
        public virtual void show()
        {
            Console.WriteLine("Hello: Base Class!");
            Console.ReadLine();
        }
    }

    class B : A
    {
        public override void show()
        {
            Console.WriteLine("Hello: Derived Class!");
            Console.ReadLine();
        }
    }

    class C : B
    {
        public new void show()
        {
            Console.WriteLine("Am Here!");
            Console.ReadLine();
        }
    }

    class Polymorphism
    {
        public static void Main()
        {
            A a1 = new A();
            a1.show();
            B b1 = new B();
            b1.show();
            C c1 = new C();
            c1.show();
            A a2 = new B();
            a2.show();
            A a3 = new C();
            a3.show();
            B b3 = new C();
            b3.show();
        }
    }
}
Output Window



http://www.codeproject.com/KB/cs/816448/image006.jpg
Explanation
The flow goes something like this:
(using overhiding as a ref for overloading)



http://www.codeproject.com/KB/cs/816448/image007.gif
Key Points
I am giving some key points about these keywords by taking reference of method overloading and overriding concepts, as these keywords are used in these mechanism.
Virtual & Override
·         Used in polymorphism implementation
·         Includes same method name and same params’
·         Used in method overriding concept
·         It is also called run time polymorphism
·         Causes late binding
New
·         It is also used in polymorphism concept
·         Includes same method name and different params’
·         Used in method overloading concept
·         It is compile time polymorphism
·         Cause early binding


No comments:

Post a Comment