2

Here is the c# code

class A {
   public int Foo(){ return 5;}
   public virtual int Bar(){return 5;}
}
class B : A{
   public new int Foo() { return 1;}     //shadow
   public override int Bar() {return 1;} //override
}

Output of

Console.WriteLine(((A)clB).Foo()); // output 5 <<<--
Console.WriteLine(((A)clB).Bar()); // output 1

How do we get this ouput.Can anyone explain the class casting process here.

Update:

And how does this show difference between shadowing and override

agasthyan
  • 725
  • 3
  • 8
  • 17

4 Answers4

6

I'll assume that

var clB = new B();

The difference between the Foo and Bar methods is that while Bar uses inheritance and polymorphism to decide what implementation to call, the Foo method hides it's original implementation.

In, a word, A.Foo() and B.Foo() are completely unrelated, they just happen to have the same name. When the compiler sees that a variable of type A invokes Foo it goes in and executes A.Foo(), since the method is not virtual, so it cannot be overriden. Similarly, when it sees a variable of the type B invoking Foo it executes B.Foo(), regardless of the actual type of the instance that is contained in the variable.

On the other hand, the Bar method is defined as virtual, and the inheriting classes can (and are expected to) override it's implementation. So whenever a call is made to Bar, regardless if it is from a variable that is declared as A or B, the method that is actually called must be found as the "latest" implementation in the hierarchy of the calling object itself, with no impact from the type of variable that was used to refer to the object.

SWeko
  • 30,434
  • 10
  • 71
  • 106
  • 1
    You: _the method is not virtual, so it cannot be inherited_ I think you mean "cannot be overridden". All methods are inherited by derived types (though some of them may not be accessible (like if they're `private`)). – Jeppe Stig Nielsen Feb 06 '13 at 14:31
  • 1
    To elaborate, when you do not specify `virtual`, then it is considered *static binding*, which means the called method implementation is determined at compile time. When it is `virtual`, then it uses *dynamic binding* and the called method implementation is determined at run time based off the actual object instance. – Matthew Feb 06 '13 at 14:36
  • @JeppeStigNielsen Yes, that's what I meant. The implementation is inherited, but the right to change it (override) is not. – SWeko Feb 06 '13 at 14:39
0

In the class B, you introduce a new method Foo with the same name and signature as the method already there (inherited from A). So B has two methods with the same name. That's not something you would do if you could avoid it.

Which of the two methods Foo that gets called, depends on the compile-time type of the variable or expression (of type A or B) used.

In contrast the method Bar is virtual. There is only one method Bar in B. No matter what the compile-time type of the expression is, it is always the "correct" override that gets called.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
0

Writing

((A)clB).Foo()

is like saying "Treat clB as if it were an A (if you can) and give me the result of Foo()". Since A has a non-virtual Foo method, it executes A.Foo. Since B's Foo method is a "new" method, it is not used in this instance.

Writing

((A)clB).Bar()

is similar - "Treat clB as if it were an A (if you can) and give me the result of Bar()". Now A has a virtual Bar method, meaning it can be overridden in base classes. Since the object is really a B, which has an override for Foo(), B.Foo() is called instead.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • You can find an answer to your second question [here](http://stackoverflow.com/questions/673779/what-is-shadowing) – D Stanley Feb 06 '13 at 14:35
0
var clB = new B();
//Uses B's Foo method
Console.WriteLine(clB.Foo());    // output 1
//Uses A's Foo method since new was use to overload method
Console.WriteLine(((A)clB).Foo()); // output 5
//Uses B's Bar Method
Console.WriteLine(clB.Bar());    // output 1
//Uses B's Bar Method since A's Bar method was virtual
Console.WriteLine(((A)clB).Bar()); // output 1
Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92