Click here to Skip to main content
15,889,116 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
class A
{
public virtual void WhoAreYou() { Console.WriteLine("I am an A"); }
}
class B : A
{
public override void WhoAreYou() { Console.WriteLine("I am a B"); }
}
class C : B
{
public new virtual void WhoAreYou() { Console.WriteLine("I am a C"); }
}
class D : C
{
public override void WhoAreYou() { Console.WriteLine("I am a D"); }
}


C c = new D();
c.WhoAreYou();// "I am a D"
A a = new D();
a.WhoAreYou();// "I am a B" !!!!
Can any one explain Whats going On?
Posted
Updated 2-Dec-13 12:53pm
v2
Comments
db7uk 2-Dec-13 18:50pm    
Apart from being a very confusing post, one with no detail, what you have tried and are trying to achieve etc I can tell you that you need to look more at object inheritance. a good example is http://stackoverflow.com/a/160095. Is this an exam question per chance?
Sergey Alexandrovich Kryukov 2-Dec-13 19:21pm    
Why? Nothing confusing for those how has any idea of OOP. OP just wants to understand how things work but got lost a bit. This is a nice code sample to demonstrate how things work. I answered the question in full, to certain level of detail. Please see Solution 1.

Better ask yourself if you understand how things work, in particular, in OP's sample, as this is very important for every software developer.

—SA
db7uk 2-Dec-13 20:14pm    
Ok Granted and very valid. The code supplied was actually better than some other posts however I guess I was confused by the "whats going on". It took me a couple of mins to figure out the actual question hence my response. It also seems you worked out the question much quicker than I so hats of to you. I like your solution. Clear and I very much doubt I would do nearly as well.

I guess my point was that the OP question was not specific enough and may not have looked into the issue that much before posting. Not a bad thing really, just one of those things.
Sergey Alexandrovich Kryukov 2-Dec-13 20:30pm    
I understand. I was a bit confused at first, too, but after more thorough reading to the very end it became clear.
Unfortunately, the fact that most of the questions we receive are quite pointless can cause some false-positive detection of bad questions...
—SA
BillWoodruff 2-Dec-13 21:12pm    
SAK wrote: "Unfortunately, the fact that most of the questions we receive are quite pointless can cause some false-positive detection of bad questions."

Which, imho, is balanced out by the number of questions which are meaningful, but which are perceived as false-negatives :)

1 solution

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
 
Share this answer
 
v5
Comments
db7uk 2-Dec-13 20:20pm    
added to that you have a nice section in here: http://www.codeproject.com/Articles/203453/Dynamic-Method-Dispatcher
Sergey Alexandrovich Kryukov 2-Dec-13 20:26pm    
Yes, thank you, but this is not directly related. See the section "Complement OOP or Abuse it?"
Here, we discuss the very heart of classic OOP.
—SA
BillWoodruff 2-Dec-13 21:13pm    
+5 Excellent response !
Sergey Alexandrovich Kryukov 2-Dec-13 23:59pm    
Thank you, Bill. (It wasn't easy. This forum is not the best place to explain fundamental mechanisms from scratch. :-)
—SA

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