What I was explaining to be more clear. If you change your code to the following you will get the results you were originally expecting, this is because polymorphism only applies to instance methods. If you look at the code you originally posted you are accessing an instance variable which will go by the declared type not the instance type which in this case is B. I think you understood this from my previous post but I thought I would elaborate.
this has nothing to do with the Object type
because Polymorphism is only for methods and not for the variables
do you know the definition of the Polymorphism?
It is "Referring to the subclass objects using the superclass reference "
SCJP 6 [86%] June 30th, 2010
OCPWCD [84%] March 26th, 2012
OCEJPAD [83%] September 6th, 2014
If you find any post useful, click the "plus one" sign on the right
regarding this thread,
there is a fundamental issue here that needs to be answered, and I have never had an answer to it, no matter who I have asked! Maybe you guys can help? to answer this question I am sure would clear up the confusion in the mind of the person who started this thread and in my own, so any ideas welcomed :-)
Bill Gorder earlier posted a quote : "do you know the definition of the Polymorphism?
It is 'Referring to the subclass objects using the superclass reference '"
That is all very well, but the question is WHY polymorphism was designed this way! And by proxy, why java was designed this way.
In the scenario where a superclass and sublass define the same methods and variables, in other words the methods are overridden and the variables are shadowed, using the standard parlance, - It is very true that, set in stone, in java the expected behaviour is that the OBJECT TYPE is always used to decide which method to take - no matter what the reference is, and that the REFERENCE TYPE is by default used to decide which field to take, in other words the one in the superclass.
That is fine and understood.
Now there are two questions from this. With shadowed variables, it is possible to DOWNCAST a supercast reference in order to bypass this default functionality, and to access the variable defined in the subclass. Similarly, if you have a subclass reference on a subclass object, you can UPCAST to get at the superclass's field.
But not for methods!
There is no way in java, at all, to get at the superclass method when the original object created was the subclass. No way at all. True, you can code super.methodname() in the subclass itself, but there is no way the 'client' programmer can request this, ie the person creating an instance of these classes and trying to use them. In addition, similarly but not quite the same, if you create a superclass reference on a superclass object, there is no way to 'downcast' to get at the overridden method in the subclass (which is fair enough as the subclass does not exist!) But when you create a subclass object in java, the superclass is implicitly created as well; the constructor is run via super().
So the questions are:
1) Why did the designers of java fundametally decree object-type for methods, and reftype for variables? Please DO NOT reply "polymorphism" - that is not a valid answer. The question then would be why does polymorphism work in that way.
To put this question another way, if the gurus could have a think: Supposing Mr.Gosling (or the OO gods before him) decided that polymorphism would be more useful if the reference type was used for both variables and methods - what would have been the ramifications of this? What would break? To my mind, this would make polymorphism a whole lot more useful - it would become true polymorphism (taking the grammatical meaning) rather than the current half-baked polymorphism, which unfortunately in java means, effectively, "inheritance-with-type-safety" which is semantically not the same thing.
2) Why did the designers of java not allow you to 'upcast' to get a superclass's methods? After all , they allowed it for variables? And in addition, they decided this feature 'might' be useful for a subclass so they provided the super.methodname() syntax. Some of my java buddies here have heard on the grapevine that super.methodname() is now considered an antipattern of sorts, but do not know why.
Seem mad? Not at all, let me give you an anology.
You have a JamesBond class and a NinjaJamesBond class, which extends JamesBond.
Both have a greeting() method and both have a String variable "apparel" so in other words, the attributes are shadowed and the behaviour is overridden. There maybe more subclasses like ScubaDivingJamesBond but for now we just need one subclass.
Now suppose we need a NinjaJamesBond object for a mission. His greeting method says "friend or foe!" and his apparel says "ninja suit." Our NinjaJamesBond object goes on a mission and gets the secrets (setting some local instance variables to carry the secrets.) Now, when he reports back to M, we don't want him to scare the bejeezus out of all and sundry in the office; we want to morph him into a normal , less specialized JamesBond whose greeting() is now "morning miss moneypenny" and his apparel is now "business suit."
But there is no way to do this in java - we can change his apparel to a suit, but not his greeting() method, as this is still saying "friend or foe."
You may retort "Ah but then he really is no longer a NinjaJamesBond. "
Not true - because NinjaJamesBond has additional attributes for all sorts of gadgets and procedures he's used on the way. M still wants to query those attributes, but does require a more sophicated greeting() !
Wouldn't it be much more useful if polymorphism worked this way?
This I feel is the crux of the problem.
If this were explained, once and for all, people (and there are a lot of them in various threads) would stop asking the same old question of "Hey! My superclass reference is accessing my subclass's method! Why is that?"