What's going on is called "the most fundamental idea of OOP, without which OOP is a not really OOP but just a meaningless name". (For many our inquirers, OOP is a meaningless name anyway. :-()
When you create a virtual function (which could be abstract), you create a slot in Virtual Method Table (VMT). If you don't know how what is VMT and how it works, you should stop reading this answer and also stop doing any programming, as otherwise continuing with either of the two would be a waste of time. The methods are called via VMT indirectly, so when you override a method, the slot in VMT is replaced with a new version of the method. The method is called according to the
run-time type, not a
design-time type (declared type) of an object. If you don't understand the distinction between run-time and design-time types… see above. That's why in first
WhoAreYou
call you have "I am a D". It would be the same if the declared type was
B
instead of
C
.
Now, so far, everything seems to be clear. Until you declare the identical object
a
with the same run-time type
D
as
A
. Here you need to understand that you have two totally unrelated VMT slots. Let's see:
"WhoAreYou"-slot 1: A.WhoAreYou —> B.WhoAreYou
"WhoAreYou"-slot 2: C.WhoAreYou —> D.WhoAreYou
They are unrelated, only have the same name. This happened because in
C
you did not override
"slot1"-WhoAreYou
with "
override
", but
reintroduced a totally new method under the same name, again, a virtual one. These two names addressing two different unrelated slots
hide each other. If your compile-time declaration is
A
or
B
, slot 1 is implied, if
C
or
D
— slot 2.
In second case,
"slot1"-WhoAreYou
gives you the latest overridden version of
A.WhoAreYou
, which was defined by
B.WhoAreYou
, hence "I am a B".
You need to learn how virtual methods work very deeply, as a conscious developer. In other words, always remember who are you. :-)
This can help to understand things on the OOP level:
http://en.wikipedia.org/wiki/Dynamic_dispatch[
^],
http://en.wikipedia.org/wiki/Virtual_table[
^].
—SA