• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Overriding Private Methods

 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Excerpt from absolutejava.com< !-- BEGIN QUESTION 4 -->
<DIV CLASS="heading">Question 4:</DIV>
Determine the result of attempting to compile and run the following code:
<PRE>
public class Tester {
public static void main(String[] args) {
System.out.println(new Sub().g());
}
private int f() {
return 2;
}
int g() {
return f();
}
}
class Sub extends Tester {
public int f() {
return 1;
}
}
</PRE>

The answer is it prints two.
But I thought the compiler should scream if you try to define a method in the subclass with the same arguments( essentially meaning we are trying to override) and reduce access visibility.
BTW, i have run in 1.1.8 and as stated, it prints 2 faithfully.
Any explanations?/
Thanks
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In the main class int f() is a private method while in subclass int f() is a public method, with overall visibility of sub class, its visibility is more than what it is in the main class. Therefore it should compile and run. Why are you saying that its visibility is reduced?
 
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
First of all, I agree with rkapoor. There is no compiler error since the accessibility modifier of super class method is private and that of the subclass method is public. Had it been the other way around, the compiler would have screamed.
Secondly, I think you touched upon a very tricky situation here. The super class method f() is private. Your subclass has a method with the same signature, but it is actually NOT overriding the super class method since private super class methods CANNOT be overridden. In fact here the subclass method simply shadows the super class method. So when the inherited method g() is called, it in turn calls the super class method f()!
If you change the accessibility of f() from private to protected, default or public, the usual overriding will take place and the code will print 1.
 
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
>>In fact here the subclass method simply shadows the super class method.
THe subclass method DOES NOT shadow the super class method.
A method can shadow other method only if it comes within its scope.
Here the scope of private f() is limited only to the super class.
HEre's an example of shadowing a method :
class Outer {
void f() {}
class Inner {
void f() {} // shadows Outer.f()
}
}
Check out this example :
class Tester {
public static void main(String[] args) {
System.out.println(new Sub().g()); }
int g() { return f(); }}
class Sub extends Tester {
public int f() { return 1; }
}

Can u explain why the above code does not compile ?
 
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
class Tester {
public static void main(String[] args) {
System.out.println(new Sub().g()); }
int g() { return f(); }}
class Sub extends Tester {
public int f() { return 1; }
}
I think this is why the above code does not compile.
When Sub().g() is evoked, since there is no such method in the subclass Sub, the call gets passed up the next higher level, and the method is found in the main class Tester.Again inside the method, a call to method f() is made, and the compiler must say that the method is not found in the class Tester.
I think this is the correct explanation..feel free to correct me...
regards,
vidya.
 
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by vidya:
[B]class Tester {
public static void main(String[] args) {
System.out.println(new Sub().g()); }
int g() { return f(); }}
class Sub extends Tester {
public int f() { return 1; }
}
Well in my opinion the call to Sub().g() makes the compiler to check g() method in the Sub class and finds it(since it's inherited) , so no problem.
but the call to f() method is not associated with any refernce so the compiler checks for the method in Tester class which it does not find ,there is no way for the compiler to know that there is f() method present in Sub class ,so it shows .
if a reference of Sub class invokes the f() method or if there is a superclass of Tester implementing f() method then the compiler can be made to stop screaming.
please do comment to correct me if i am not Right!
satish varanasi

[This message has been edited by Satish Varanasi (edited August 13, 2000).]

 
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
here r two questions :
can private methods be overridden : No
Because private methods r implicitly final so they can't be overridden.
Are private methods inherited : No
This is as per Java Language specification. When a method is declared as private, it is not available to any other class, ie it is not inherited. So if its not inheried it cannot be overridden.
public class Tester {
public static void main(String[] args) {
System.out.println(new Sub().g());
}
private int f() { return 2; }
int g() { return f(); }
}
class Sub extends Tester {
public int f() { return 1; }
}
In this case sub().g() is called, but sub has no g() method of its own. but it extends Tester, so it gets g() from superclass, right? but after this im also a bit confused.
Can anyone explain after that?
Thanks
Sanjeet

Originally posted by Satish Varanasi:

Originally posted by vidya:
[B]class Tester {
public static void main(String[] args) {
System.out.println(new Sub().g()); }
int g() { return f(); }}
class Sub extends Tester {
public int f() { return 1; }
}
Well in my opinion the call to Sub().g() makes the compiler to check g() method in the Sub class and finds it(since it's inherited) , so no problem.
but the call to f() method is not associated with any refernce so the compiler checks for the method in Tester class which it does not find ,there is no way for the compiler to know that there is f() method present in Sub class ,so it shows .
if a reference of Sub class invokes the f() method or if there is a superclass of Tester implementing f() method then the compiler can be made to stop screaming.
please do comment to correct me if i am not Right!
satish varanasi
[This message has been edited by Satish Varanasi (edited August 13, 2000).]


 
vidya
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, I agree with Satish Varanasi. Had there been a method f() in the superclass of tester, it would have been invoked. But in this case, since the class Tester doesnt seem to extend anything, the compiler must give an error.
Now, I got all messed up with the code posted by Sanjeet:
This is it:
1. public class Tester {
2. public static void main(String[] args) {
3. System.out.println(new Sub().g());
4. }
5. private int f() { return 2; }
6. int g() { return f(); }
7. }
8. class Sub extends Tester {
9. public int f() { return 1; }
10.}
Sanjeet,
I thought the code wont compile,but to my surprise, I found that it compiles perfectly well. This is my explanation ,but I got confused at the end.
Sub().g() will invoke the method g() in the class Tester.
Inside g(),as a response to the statement return f();
the private method f() (in line 5) will be invoked.
This is legal because here, new Sub()(in line 3) is actually
creating a reference to the class Tester.Since a private method can be invoked only by an instance of the class to which it belongs,the method f() in the class Tester is invoked.
then, I tried declaring so: (note line 3)
1. public class Tester {
2. public static void main(String[] args) {
3. Sub ii = new Sub();
4. System.out.println(ii.g());
5. }
6. private int f() { return 2; }
7. int g() { return f(); }
8. }
9. class Sub extends Tester {
10.public int f() { return 1; }
11.}
Here too, the code compiles perfectly well..
ii is an instance of Sub, which invokes g() in the superclass, which in turn invokes the private method f() in the superclass (which can be invoked by only an instance of the class to which it belongs ).
what do I gather from this? Because Sub 'is a' Tester , a reference to Sub (ii here) is able to access a private method in its Superclass??? But this is not what the definition for "private" says....
what am I missing?
waiting for the reply,
regards,
Vidya.
 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As per Java2 Certification Study Guide Page 79:
The rules for overriding can be summarized as follows:
- A private method may be overridden by a private, friendly, protected or public method.
- A friendly method may be overridden by a friendly, protected,or public method.
- A protected method may be overridden by a protected or public method.
- A public method may only be overridden by a public method.
 
Jayakumar Thirumalai
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Try with "'public int f()' instead of 'private int f()'".
1. public class Tester {
2. public static void main(String[] args) {
3. System.out.println(new Sub().g());
4. }
5. public int f() { return 2; }
6. int g() { return f(); }
7. }
8. class Sub extends Tester {
9. public int f() { return 1; }
10.}
The result is "1".
Reason - f() in Sub overrides f() in Tester().
When f() in Tester was private,
g() can execute f() in Tester because g() is a method in Tester. Any method in Tester can access private variables and methods.
Eventhough g() has access to both f() in Tester and f() in Sub, it prefers (???) to execute its own private f() method rather than public f() method in Sub.
is this more confusing !!!

 
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can any JLS experts (I know I'm not ) tell us something about this?
This is tricky because even though f() is private the code was able to call it through the inherited g() method. Is there a valid reason for this?
Thanks.
[This message has been edited by Ken Lai (edited August 13, 2000).]
 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1. public class Tester {
2. public static void main(String[] args) {
3. System.out.println(new Sub().g());
4. }
5. private int f() { return 2; }
6. int g() { return f(); }
7. }
8. class Sub extends Tester {
9. public int f() { return 1; }
10.}
when a new sub().g() is called ,first the JVM checks for the method definition for g() on the called Object which is Sub,its not present in the class definition for Sub ,so it has to traverse up the heirachy where it will find a method
int g() { return f() ; }

the above method defintion is translated by compiler as
int g() { return this.f() }
now the Owner of method g() is Tester ,
But BY virtue of inheritance this method is accessible by Childrens of Tester also.
when the Body says this.f(),the method that is to be executed should be choosen from the same class in which the g() is defined.
Hence the f() in the parent class Tester will be Executed .
on the Otherhand if the g() was overriden and f() was also defined [note if f() will not be defined then surely compiler error will occur] in SUB then f() in SUB will be Accessed.
1. public class Tester {
2. public static void main(String[] args) {
3. System.out.println(new Sub().g());
4. }
5. private int f() { return 2; }
6. int g() { return f(); }
7. }
8. class Sub extends Tester {
9. public int f() { return 1; }
10 int g() { return f(); }
11.}

 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hello !
1) in the above problem the method int g() is inherited by class class Sub.so there is no problem in printing 2 as output.
2) method private int (){return 2;} is not overridden becuse java does not allow to override a private method.
3)in java there is no word like shadowing.even if a method in inner class has same signature as that of outer class the method is not overridden. it is simply a local method like a local variable and any local member has higher priority than outer one.
4) in the above problem if we define method int g(){return f();}
as a private it will give a compiler error.
5)in the above problem if we define method private int f(){return 2;}as a protected it will give a output 1.
please write me if any one has any other idea.
 
Satish Varanasi
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi folks,
1. public class Tester {
2. public static void main(String[] args) {
3. System.out.println(new Sub().g());
4. }
5. private int f() { return 2; }
6. int g() { return f(); }
7. }
8. class Sub extends Tester {
9. public int f() { return 1; }
10.}
I overlooked line 5 in my prevoius reply:my apology.
I think i have an explanation to offer.As the question is from absolute java,the explanation offerred by them : for private & static methods the compiler does not generate code for run time binding because they cannot be overriden,so they are resolved at compile time ,Hence no question of DynamicMethod lookup.i feel iam clear
Try with static modifier for f() in both classes,
any other view!!!
satish varanasi
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree with Satish. Static methods, private methods, and final methods are statically bound; that is, they're resolved at compile-time. Therefore, the type of the reference variable (not the type of the actual object) determines which version to use.
The thing that is confusing here is that when the object is created in "System.out.println(new Sub().g());" it isn't being assigned to a visable reference variable. If we saw, either "Tester t1 = new Sub(); t1.g();" or "Sub s1 = new Sub(); s1.g();" it might be easier to see what's going on (given the rules listed in my first paragraph).
Don
[This message has been edited by DaB (edited August 14, 2000).]
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes satish is correct the private methods are resolved at compile time itself.So No probs in accessing the f() of parent class Tester.
 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello All,

Here's an explanation. I guess, it fits.
When a Base class has a method as Private its not available for overriding/inheritance. Also, private and static components are resolved/bound at Compile time. Another important point is : If a method in a class calls another member method the default is object "this".
Looking at Tester class, when compiler comes across new Sub().g(), compiler looks for method g() in Sub. This lookup fails and hence compiler looks in higher up at super class Tester, where it finds g(). when it tries to look for f(). Since f() is private in Tester it cannot be overridden/inherited. So any reference to f() from Tester::g() is bind-ed to Tester::f().
That should explain why it prints "2".
When you declare Tester::f() not as private i.e. either protected, default or public you open it (or it available) for overriding and inherting by Sub classes. At compile time now when the compiler comes across this more open declareation it leaves the method call for Late binding (dynamic reference) and hence the Sub::f()overides it and displays '1".
Do I sound confusing ? Is the explanation wrong ? Correct Me
Anytime,
SVR.
svr_76@yahoo.com
svr_76@hotmail.com
 
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

So does that imply thet what is written on page 79 of RHE
is wrong.It clearly states :
- A private method may be overridden by a private, friendly,
protected or public method.

Anurag
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yeah, you can't really trust RHE for accuracy on the fine points. William Brogden or Mughal & Rasmussen would have fixed this by now, at least in their online errata. I guess RHE figure that since they know this particular point won't come up on the exam, it doesn't matter if it's right or not. RHE are fine for passing the exam, but not for learning Java in general, IMO.
 
vidya
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another observation:

public class Tester {
public static void main(String[] args) {
Sub ii = new Sub();
System.out.println(ii.g());
}
private int f() { return 2; }
int g() { return f(); }
}
class Sub extends Tester {
public int f() { return 1; }
}

Yikes!! RHE may be wrong for the above code,
but is right on the code below:
The code below returns 1 ,which means a private method is overridden by a public method.
Where is this taking me???

public class Tester {
public static void main(String[] args) {
Sub ii = new Sub();
System.out.println(ii.g());
}
private int f() { return 2; }
//int g() { return f(); }
}
class Sub extends Tester {
public int f() { return 1; }
int g() { return f(); }
}

regards,
Vidya.
 
thomas
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, Vidya. Here, the private super class method is NOT overridden by the sub class method. The sub class method is just another method which happen to have the same signature as the super class method. They are not related.
Also, thanks Deepak for pointing out my incorrect usage of the term 'shadows'.
 
svr
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,
Here's a statement from the Sun's JAVA LANGUAGE SPECIFICATION PDF. Who's more Authentic that 'The Father'. Its say :
<Quote>
6.6.8 Example: private Fields, Methods, and Constructors
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. In the example:

class Point {
Point() { setMasterID(); }
int x, y;
private int ID;
private static int masterID = 0;
private void setMasterID() { ID = masterID++; }
}
The private members ID, masterID, and setMasterID may be
used only within the body of class Point. They may not be
accessed by qualified names, field access expressions, or
method invocation expressions outside the body of the
declaration of Point.
<UnQuote>
So that means Private members are not inherited/overridden. Derived class can have a method with the same signature as the Base class private method, But this method will not override the
Base class method.
Its getting 2 much Confusing !
Lets Keep learning,
-SvR
svr_76@yahoo.com
svr_76@hotmail.com
 
Sanjeet Karamchandani
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
Referring to Vidya,
Excuse ME but the answer printed by ur code is 2. Try again.
This is the code :
public class Tester {
public static void main(String[] args) {
Sub ii = new Sub();
System.out.println(ii.g());
}
private int f() { return 2; }
int g() { return f(); }
}
class Sub extends Tester {
public int f() { return 1; }
}
Well as far as i know is private methods cannot be overridden. I agree with svr. I think its because of a internal reference(secret reference as called by Bruce Eckel) passing. I think the program flows as follows
when sub().g() is called a object of sub is created and g() is called for it. but g() is not available in sub so the compilier looks for the method in its superclass(Tester) it finds g() there.
now g() calls f(), note there is no reference while calling with f() so it can be said as this.f(). Now since f() is private the compiler doesn't go to see whether its overridden(coz it can't be overridden) so it executes the superclass version of f().
I hope its clear and more importantly correct.
If anything wrong, let me know
Thanks
Sanjeet
 
vidya
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well..let me ask you this basic question.
 
vidya
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry abt that..I accidentally sent it...
Let me just ask this ......

Let me quote Thomas ."The sub class method is just another method which happen to have the same signature as the super class method."
Isn't this what we call overriding? Or am I missing something?
I think I should go by what the JLS says, but unfortunately I am not getting convinced. ( Once again, please refer to the second code attached in my earlier posting)

Referring to Sanjeet,
You are absolutely right regarding the code you used. But that's not the code I was talking about in my earlier posting. I was referring to the second code attached, where I said the code returns 1. You might want to please try that.
regards,
Vidya


 
Sanjeet Karamchandani
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Vidya,
Well, i would like to clear it.

Quoted by Thomas ."The sub class method is just another method which happen to have the same signature as the super class method."
I think here he is talking abt a private method in superclass and a method in subclass with the same signature.
EX :
class A {
private void amethod() { }
}
class B extends A {
public void amethod() { }
}
Here u can't say that amethod is overridden coz its private, but the subclass has a method with the same signature, isn't it? So this is not overridding
Now abt ur code :
public class Tester {
public static void main(String[] args) {
Sub ii = new Sub();
System.out.println(ii.g());
}
private int f() { return 2; }
//int g() { return f(); }
}
class Sub extends Tester {
public int f() { return 1; }
int g() { return f(); }
}
In this case it should print one. Well here u r calling the method g() thatz in subclass which in turn calls f()( which could be written as this.f() ) so the compiler searches it first in subclass and finds the method defination in subclass itself and uses it, isn't it straight forward?
Thanks
Sanjeet
 
svr
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi EveryBody,

Are we all on the same page ? Private Methods cannot be Overidden/inherited. Private access modifier restricts that members access to other members within the scope of the same Class. So derived class does not has access to it.

Time to change the name of this Thread !!!
:-)
SvR.
 
vidya
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi!
I think I am getting it now....Thanks friends, for your time,
especially Sanjeet and Thomas.
regards,
Vidya.
 
We noticed he had no friends. So we gave him this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic