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.