GeeCON Prague 2014*
The moose likes Beginning Java and the fly likes Polymorphism and Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Polymorphism and "this" keyword, an interesting Q.." Watch "Polymorphism and "this" keyword, an interesting Q.." New topic
Author

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

Jon Lee
Ranch Hand

Joined: Mar 04, 2005
Posts: 134
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 ]

SCJP 5.0 - 98% (2007)<br />SCWCD 1.4 - 97% (2007)
Giovanni De Stefano
Ranch Hand

Joined: Aug 17, 2004
Posts: 144
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


SCJP 1.4
James Carman
Ranch Hand

Joined: Feb 20, 2001
Posts: 580
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.


James Carman, President<br />Carman Consulting, Inc.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
With other words, fields aren't polymorphic, only (non-static) methods are.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Jon Lee
Ranch Hand

Joined: Mar 04, 2005
Posts: 134
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

Joined: Mar 04, 2005
Posts: 134
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

Joined: Jul 11, 2001
Posts: 14112
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

Joined: Mar 04, 2005
Posts: 134
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

Joined: Dec 06, 2001
Posts: 3061
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


Java API Documentation
The Java Tutorial
Layne Lund
Ranch Hand

Joined: Dec 06, 2001
Posts: 3061
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

Joined: Mar 04, 2005
Posts: 134
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 ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Polymorphism and "this" keyword, an interesting Q..