Click here to Skip to main content
15,904,638 members
Please Sign up or sign in to vote.
3.38/5 (7 votes)
See more:
Hi all,
I have gone through one of the article which shows difference between Overriding & Method Shadowing. I was trying to implement method shadowing but not able to get it so can anybody helps me out ?


class Base
    {
        public void PrintOnScreen()
        {
            Console.WriteLine("Base Method");
        }
    }
    class Derive : Base
    {
        public new void PrintOnScreen()
        {
            Console.WriteLine("Derive Method");
        }
    }
    class MethodShadowingDemo
    {
        public static void Main(string[] args)
        {
            Base objDerive = new Derive();
            objDerive.PrintOnScreen();
            Console.ReadLine();
        }
    }
In this example according to shadowing concept derived class method is to be called but instead it's calling base class method so i am bit confused how the concept actually works ?
Posted
Updated 27-Apr-11 19:47pm
v2

This can be a bit confusing, so lets have a simple example:
public class A
    {
    public void P() { Console.WriteLine("A:P"); }
    public virtual void Q() { Console.WriteLine("A:Q"); }
    }
public class B : A
    {
    public new void P() { Console.WriteLine("B:P"); }
    public override void Q() { Console.WriteLine("B:Q"); }
    }
class Program
    {
    static void Main(string[] args)
        {
        Console.WriteLine("Started");
        A a = new A();
        B b = new B();
        A r = b;
        a.P();
        a.Q();
        b.P();
        b.Q();
        r.P();
        r.Q();
        Console.WriteLine("Stopped");
        Console.ReadLine();
        }
    }
When we run this, we get:
Started
A:P
A:Q
B:P
B:Q
A:P
B:Q
Stopped
When we declare a variable of type A, we always call "P" from class A, even if we assign an instance of the derived class to it. We call "Q" from the instance type, rather than the variable type.
When we declare a variable of type B, we always call "P" and "Q" from class B.

"P" is a hidden method (shadowed is VB parlance, hidden is C#): The derived class version will be used only if you are explicitly referring to a member of a derived class. If you are accessing it via a base class, the base class version will be used.

"Q" is an overridden method - any reference to it goes to the most derived class definition, rather than the base class. If no such definition exists, it will use the base class definition.
 
Share this answer
 
Comments
Olivier Levrey 28-Apr-11 5:01am    
Perfect answer. Clear and comprehensive. Have a 5.
sidpab 19-Mar-12 6:32am    
Wow!! what a Cool solution. the topic is best explained here. hats off buddy. Thanks to codeproject
class Base
{
        public void PrintOnScreen()
        {
            Console.WriteLine("Base Method");
        }
}
class Derive : Base
{
        public new void PrintOnScreen()
        {
            Console.WriteLine("Derive Method");
        }
}
class MethodShadowingDemo
{
        public static void Main(string[] args)
        {
            Base objDerive = new Derive();
            objDerive.PrintOnScreen();
            Console.ReadLine();
        }
}

The output would be
Base Method
Because the base class method is not marked as virtual. If it is marked as virtual and if there is any overridable method is available then you will get "Derive Method" output.

Now I am changing the code
class Base
{
        public virtual void PrintOnScreen()
        {
            Console.WriteLine("Base Method");
        }
}
class Derive : Base
{
        public new void PrintOnScreen()
        {
            Console.WriteLine("Derive Method");
        }
}
class MethodShadowingDemo
{
        public static void Main(string[] args)
        {
            Base objDerive = new Derive();
            objDerive.PrintOnScreen();
            Console.ReadLine();
        }
}

still the output would be
Base Method
because even the base class method is marked as virtaul but it doesnot have any overridable method in the derived class. Even if you remove the "new" keyword from the Base class method.

You will get output as "Derive Method" only if you marked child class function as overridable and parent class function as virtual.
class Base
{
        public virtual void PrintOnScreen()
        {
            Console.WriteLine("Base Method");
        }
}
class Derive : Base
{
        public override void PrintOnScreen()
        {
            Console.WriteLine("Derive Method");
        }
}
class MethodShadowingDemo
{
        public static void Main(string[] args)
        {
            Base objDerive = new Derive();
            objDerive.PrintOnScreen();
            Console.ReadLine();
        }
}


Hope you can understand now.
 
Share this answer
 
v2
Comments
Olivier Levrey 28-Apr-11 5:03am    
Good answer. Have a 5.
nit_singh 28-Apr-11 5:27am    
Thanks Olivier
Member 7815998 28-Apr-11 5:16am    
I understood all of this above but then not getting clear picture that why should we use "new" keyword in front of child class method ??? whn we can easily access it by just creating object of child class..?? hope u understood my problem.
nit_singh 28-Apr-11 5:29am    
new keyword provides a new implementation of the parent class function (if available) so you will not get warning.
Member 2564240 28-Apr-11 9:38am    
Is the new keyword is only used to remove the warning message or there is some other use too?
These guys were pretty clear about the topic :) Thumbs up, codeproject is getting better by the day :D

In addition to those, just a small point of view on why and when you should use new keyword

Ok, back to the basics. When you inherit from a class, the methods marked with either public or protected will be available to the child class. right? So while designing, you decide that I might need more expanded behavior or different behavior from these methods. Let's take an example.
C#
public class Bird {
     public void Eat() {
          Console.WriteLine("Eating....");
     }

     public virtual void Fly() {
          Console.WriteLine("Flying....");          
     }
}

Few things to notice, since every bird is eating, you know that's not going to change, so you don't intend to change it's behavior in child classes. But some birds can't fly, so you know it's going to change, so you are marking that method with virtual keyword. You can achieve the same thing, by abstract classes but it's a different lesson :)

So let's implement 2 birds classes
C#
public class Robin : Bird {
     public override void Fly() {
          Console.WriteLine("Flying Fast....");
     }
}
public class Ostrich : Bird {
     public override void Fly() {
          Console.WriteLine("Cannot fly");
     }
}

Now, I am going do something crazy :D Laugh all you want, but I could not come up with a better example this quickly. But I know it'll help you understand the concept.

So let's imagine, you are want to include disabled birds who can't eat. Now this was not expected in the original design. I.e. it was not intended in the design. So you can go back to the original design and decorate the Eat() method with override.

But this is not possible when you are using someone else's code. I.e. you don't have the source code to edit and update but only the compiled DLL. So now what? That's where new keyword helps you out.
C#
public class DisabledBird : Bird {
     public override void Fly() {
          Console.WriteLine("Cannot fly :(");
     }

     public new void Eat() {
          Console.WriteLine("Cannot eat :(");
     }
}

The new keyword serves 2 purposes.
1. Allows you to hide methods of parent classes and implement a different method for the same signature.
2. Allows you to keep track of methods that you did like that. So that it would not confuse you when you look in to the code later on.

NOTE: This is NOT mean that you should not design your code or overriding can be just ignored. If you do that, you'll quickly lose the ability to maintain your code. This should be only used for exceptional cases like when you are using a toolkit or a library.

Damn, this turned out to be an article :P Apologies

Hope this helps :) Regards
 
Share this answer
 
v2
Comments
Wayne Gaylard 29-Apr-11 4:21am    
Thanks for the lesson. You should write articles, as you have a nice writing style. Easy to understand.
CodeHawkz 29-Apr-11 4:44am    
:) Thanks, but I am not that good plus I didn't find a suitable topic. There are almost everything you want in the net, you just have to search for it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900