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 ]
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!
See what that prints.
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 ]
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.
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.
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?
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.
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.
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 ]