File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
Win a copy of Soft Skills: The software developer's life manual this week in the Jobs Discussion forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Polymorphism and "this" keyword, an interesting Q..

 
Jon Lee
Ranch Hand
Posts: 134
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paste the source code first:


And the output is:


Pls note the second and thrid line of output.

My question is: When invoke son1.getName(), why "this" refer to the object of Class Son, but the value of this.name is "father"??

Any pro can explain this??
[ May 06, 2005: Message edited by: Jon Lee ]
 
Giovanni De Stefano
Ranch Hand
Posts: 154
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jon Lee,
this is question I asked myself too...I don't know if it's a pro thing, but I have the answer (which you DO NOT find in books...):
you inherit METHODS and NOT INSTANCE VARIABLES

Basically, the instance variables name in father is NOT inherited, but it is hidden by the son, this is called shading a variable.

I hope I made myself clear, it's late here and I am still in front of a computer!

Giovanni
 
James Carman
Ranch Hand
Posts: 580
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are "hiding" the name field of the super class. The code in the Father class has to refer to its public field called name. But, when you declare a field in the subclass, Son in this case, with the same name as the field in the superclass, you "hide" the superclass' field. This should really bake your noodle. Try this...



See what that prints.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
With other words, fields aren't polymorphic, only (non-static) methods are.
 
Jon Lee
Ranch Hand
Posts: 134
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thnx for your comments, guys. I have read each post very carefully but still cant figure out the answer of my question. My questions is:

When you invoke son1.getName(), the java interpreter invoke the getName method defined in the superclass Father with an implicit parameter "this" which refer to son1, one object of Son. Since "this" refers to son1, "thie.name" should refer to the "name" field of son1, whose value should be son1.

I have used C++ for a long time. I think the this keyword in Java is similar to a object pointer in C++. In C++, if the pointer points to one object, let's say son1, the value of this->name will absolutely be "son1", not "father". Maybe Java is a little bit different from C++ on this issue. Can anyone tell me the mechanism behind this? Thnx a lot
[ May 07, 2005: Message edited by: Jon Lee ]
 
Jon Lee
Ranch Hand
Posts: 134
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have figured it out, the following is my thought:

Rule No1: subclass inherits all the methods and fields in its superclass. But subclass can not access the private methods and fields of the superclass.

Rule No2: "When you create an object of the derived class, it contains within it a subobject of the base class. This subobject is the same as if you had created an object of the base class by itself. It�s just that from the outside, the subobject of the base class is wrapped within the derived-class object." -- From <<Thinking in Java>>

Based on the above two rules, I have the answers to my question:
Son class has two "name" field. One belongs to Son class. The other is inherited from the Father class and it is hidden by the "name" field of Son Class.

Object of Son class has an subobject of Class Father. The subobject contains a "name" field whose value is "father" and it is hidden from the outside. When invoke son1.getName(), son1 is upcasted to the type Father because class Son does not override this method. After the upcasting, interpreter regards son1 as a reference to that subobject which contains a name field with value "father". That's why you can "father" in the second line of output.

The value of "this" is a reference to the object, son1 in this case, which originally invoke the method.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jon Lee:
When invoke son1.getName(), son1 is upcasted to the type Father because class Son does not override this method. After the upcasting, interpreter regards son1 as a reference to that subobject which contains a name field with value "father". That's why you can "father" in the second line of output.


Not exactly.

What you need to understand here is the difference between late binding and early binding.

Binding is the mechanism of how the system decides what actual entity is meant by using a symbolic name.

Java uses late binding for instance methods, that is, the compiler just stores the symbolic name in the byte code, and the VM decides at runtime which method to execute. That allows it to base the decision on runtime information such as the actual type of an object - which results in polymorphic behaviour.

For fields, though, (as well as for static methods), Java uses early binding. That is, the symbolic name is resolved to the actual entity at *compile* time. Now, when the compiler compiles the Father class, it doesn't know about a field of the same name in a subclass - the only fields it can access are those accessible from Father. So it's hardcoded into the byte code that Father.getName will always access Father.name, no matter what type the actual object (this) is of.

Does that help?
 
Jon Lee
Ranch Hand
Posts: 134
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes mate. Your post make a lot sense to me. Thnx so much. I confuse "this" in java with the pointer in C++....
 
Layne Lund
Ranch Hand
Posts: 3061
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jon Lee:
Yes mate. Your post make a lot sense to me. Thnx so much. I confuse "this" in java with the pointer in C++....


In my experience, the "this" keyword in C++ behaves the same as it does in Java. In fact, if you translate this program into C++, I am willing to bet that you will see the exact same behavior.

Layne
 
Layne Lund
Ranch Hand
Posts: 3061
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was bored and translated it into C++ for you

I am not to familiar with C++'s RTTI, so I didn't bother with trying to get the info similar to Java's getClass() method. Other than that the output was similar:

Note that it still prints "father" instead of "son1" like you might expect if you didn't understand early and late binding as described above.

Layne
 
Jon Lee
Ranch Hand
Posts: 134
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you so much, Layne Lund. I am too lazy to translate the java code to C++ and hope there will be some bored guys can do it for me. Then you pop up.

Now I have a more accurate understanding about polymorphism and late binding. Thnx all guys in this thread. Cheers,
[ May 09, 2005: Message edited by: Jon Lee ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic