Win a copy of Learn Spring Security (video course) this week in the Spring forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Question on Overriding

 
Bala Raj
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What will be output of the following program?

A. Compile error can't override the private method print()
B. From Parent
From child
C. From Parent
From Parent
D. From child
From child
I thought the answer would be B, but the output is C. Can any one explain me how?
Thanks,
Bala
 
Manish Hatwalne
Ranch Hand
Posts: 2591
Android Firefox Browser Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think all options are incorrect.
There are 3 print statements, so o/p will be -
<pre>
From Parent
From Parent
From child
</pre>
P1 is of type OverRidingParent, moreover print() method in OverRidingParent class is private, hence all function calls get resolved at comile time and do not display any polymorhic behaviour at runtime. Had it (print() in OverRidingParent) been a protected or public method, the output would have been -
<pre>
From Parent
From child
From child
</pre>
because of overriding. Third call c1.print(); is straight forward and produces expected o/p.
HTH,
- Manish
[This message has been edited by Manish Hatwalne (edited October 09, 2001).]
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
private methods are not inherited.
The virtual machine looks in the declared type (or supertypes) of the variable (OverridingParent) for the method to invoke. As it finds a private method it doesn't looks for possible overriding methods declared in the type of the object (OverridingChild for the second invoacation).
Looking for methods in the type of the object is done for instance methods, not for private or static methods. The last two are said to be bound statically, while instance methods are bound dinamically (this is called polymorphism)
Anyway its very important to look for the declaration of the method first in the declared type (compile type) or supertypes of the variable, not in the type of the reference pointed to by the variable.
 
Scott Cochrane
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Manish Hatwalne:
[B]I think all options are incorrect.
There are 3 print statements, so o/p will be -
<pre>
From Parent
From Parent
From child
</pre>
I tested this and did indeed get the above output. The third print I understand. However when your say:
"moreover print() method in OverRidingParent class is private, hence all function calls get resolved at comile time and do not display any polymorhic behaviour at runtime."
I don't get this! I thought that java used late-binding for method calls and with the print method being private how can it be called from outwith the object (or is this possible here because the main method is in the class). Before I ramble on more could someone clarify further?
scott
 
Manish Hatwalne
Ranch Hand
Posts: 2591
Android Firefox Browser Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

"moreover print() method in OverRidingParent class is private, hence all function calls get resolved at comile time and do not display any polymorhic behaviour at runtime."
I don't get this! I thought that java used late-binding for method calls ...

Private methods are neither inherited, nor overriden. They staticly bind (early binding) to the the declared type variable (p1 here in first 2 cases) at compile time. Late binding happens with overriding. I think, Jose explained it quite clearly.

...and with the print method being private how can it be called from out with the object (or is this possible here because the main method is in the class).

Right, that's the reason. main happens to be a static method of the class, besides being an entry point.


Hope this makes it clear.
- Manish
 
Madan, Gopal
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a direct quote from Khalid A. Mughal's book.
"Any final, static and private methods in a class cannot be overridden"
I understand "final" modifier for obvious reason.
I am able to compile 2 classes, one inherited from another, with overridding private methods. But when I try to invoke this method on an object from an outside class ( with main(String[] args) ), for accessibility reasons, I get compile error.
As for as static methods, I was able to compile and successfully invoke these static methods on ancestor and descendant class objects. But ofcourse, i didn't get any inherited/overridden functionality. Because, these were static methods and not associated with any objects, they were resolved against their class and not against any polymorphic objects.
I guess, what i am trying to emphasize(or trying to understand) here in my ramblings is:
Khalid's quote means, you don't get any benefit from inheritance when you try and successfully override a static method - you can compile but don't get what you expected.
You can compile and override private methods, but you fail miserably when you try to invoke these private methods outside it's class.
I am not making any new point, but I didn't want to open a new post for this topic, either. I just wanted somebody to concur or disagree and shed some light on this.
Thanks and sorry for this long post
Madan
 
Bala Raj
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For testing purpose I put c1.print() and forgot to take it before posting. Sorry.
Bala
 
Nain Hwu
Ranch Hand
Posts: 139
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If all of us can keep Jose's point in mind, lots of trouble/doubts can be avoided.

Anyway its very important to look for the declaration of the method first in the declared type (compile type) or supertypes of the variable, not in the type of the reference pointed to by the variable.
 
Manish Hatwalne
Ranch Hand
Posts: 2591
Android Firefox Browser Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Madan -
I am able to compile 2 classes, one inherited from another, with overriding private methods. But when I try to invoke this method on an object from an outside class ( with main(String[] args) ), for accessibility reasons, I get compile error.

You *can not* override a private method, simply because private method is not visible in subclass. You are allowed to define a method with same name, parameters, return type in the subclass, but it has no relation with the private method of the super class.
Overriding essentially means choosing the correct implementation of the method depending upon its actual runtime created object.
Also, see JLS - 6.6.8, it says
"A private class member or constructor is accessible only within the class body in which the member is declared and is not inherited by subclasses."

As for as static methods, I was able to compile and successfully invoke these static methods on ancestor and descendant class objects. But of course, i didn't get any inherited/overridden functionality. Because, these were static methods and not associated with any objects, they were resolved against their class and not against any polymorphic objects.
I guess, what i am trying to emphasize(or trying to understand) here in my ramblings is:
Khalid's quote means, you don't get any benefit from inheritance when you try and successfully override a static method - you can compile but don't get what you expected.

Again, you *do not* override a static method, this is called "hiding". A static method with same signature in the subclass hides the method in the base class (super class). Hence you do not get polymorphic behaviour. See JLS for more details -
8.4.6.2 Hiding (by Class Methods)
8.4.8.5 Example: Invocation of Hidden Class Methods

You can compile and override private methods, but you fail miserably when you try to invoke these private methods outside it's class.

Nah, no overriding for private methods.
You *can not* invoke/use private methods outside the body of a class in which they are declared. Only members of that class can access the private method and this is totally unrelated to overriding. This is an access modifier issue, which defines accessibility of the methods.

I am not making any new point, but I didn't want to open a new post for this topic, either. I just wanted somebody to concur or disagree and shed some light on this.

I hope this is clear now, do let us know.

HTH,
- Manish
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic