Reputation: 725
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
Upvotes: 2
Views: 155
Reputation: 30882
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.
Upvotes: 6
Reputation: 21245
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
Upvotes: 0
Reputation: 152521
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.
Upvotes: 0
Reputation: 61952
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.
Upvotes: 0