• 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
  • Tim Cooke
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

Method in constant specific class body gets hidden.

 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Output:

I know that private members in an inner class is actually private to the top level class.
So private 'method()' is accessible anywhere within Main class.
What's causing public method() to be shadowed?
Is there a way to access the public method() defined for GREEN?
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Cyril. Welcome to the Ranch!

You can't override a private method. So, have you tried changing the default version to public or protected? I think you'll see different behaviour then.
 
Cyril Sadasivan
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matthew Brown wrote:Hi Cyril. Welcome to the Ranch!

You can't override a private method. So, have you tried changing the default version to public or protected? I think you'll see different behaviour then.



Thanks Matthew.
Yes, it works for protected or coderanch.
Sure private methods are not overridden.
But GREEN must have 2 'method()'s in it. Right?
How do we use the public method if we want to, in this context?
 
Ranch Hand
Posts: 91
Firefox Browser C++ Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Private methods are not overriden in the sense that the two methods become completely different due to visibility issues.

What I don't get is why the instance Color.GREEN cannot call its own version of method().

Why does the compiler not call GREEN's method()? I thought it would be like this is(what Matthew said) if it were the other way round, i.e., GREEN's method() were private.

Edit : If GREEN's method() were private, the code would not compile. The compiler would state that overriding was not possible.
 
Cyril Sadasivan
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I supppose this is what the enum code within the class boils down to. This has the same output as the previous one.
Finding the explanation from this code should be simpler
 
Pritish Chakraborty
Ranch Hand
Posts: 91
Firefox Browser C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It still doesn't ring any bells...

You've rewritten it and made GREEN become an instance of an anonymous subclass of Color. Fine.

But why at runtime is GREEN not redirected to its own method?

private and public method()s are both completely different.

Is it because of this 'difference'? There is no sense of overriding...so the overriden method will never be called.

Is that it?
 
Matthew Brown
Bartender
Posts: 4568
9
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The problem is that when you add a method to a constant specific body, you're really creating an anonymous inner class. And because you have no way of referring to that class from outside (because it's anonymous), you have no way of accessing the method unless the method is declared in the original class.

So if you declare the method in a way that is overrideable, all is fine. If you make that method private, you've hidden the constant-specific method in a way you can never recover.
 
Cyril Sadasivan
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matthew Brown wrote:The problem is that when you add a method to a constant specific body, you're really creating an anonymous inner class. And because you have no way of referring to that class from outside (because it's anonymous), you have no way of accessing the method unless the method is declared in the original class.

So if you declare the method in a way that is overrideable, all is fine. If you make that method private, you've hidden the constant-specific method in a way you can never recover.



Thanks Matthew. I think I got it.

Just to make it clear..

While it's clear that the actual object referred by GREEN has 2 'method()'s in it and that overriding doesn't happen, which method gets invoked depends on the 'type' of reference used to invoke the method.
In the code, variable GREEN of type Color is referring an object which is a (anonymous) subtype of Color(super class reference referring a sub class object).
Thus the 'method()' which gets invoked is the one which the super class (Color) is aware of.

Pritish Chakraborty wrote:why at runtime is GREEN not redirected to its own method


GREEN is redirected to it's own method, the one which it knows about.

The below code shows how a random method in anonymous class body can be invoked with it's own reference.



Output:

 
Ranch Hand
Posts: 88
IBM DB2 Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Cyril, based on Matthew's reply, I did modify your code a bit as follows. Hope this will help to understand the concept.

Output:
 
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Case 1:

Output:


Case 2:

Output:


I am a little bit confused and here is my idea:
In case1, the GREEN refers to an annoymous, Color's subtype class. GREEN overrides the public method.
In case2, the GREEN class does not override the private method in Color because private method cannot be overriden. GREEN has it own public method.
However, in the main method, GREEN.method() actually refers to the private method because GREEN is a Color and GREEN can "see" the private method.
 
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Helen Ma wrote:In case1, the GREEN refers to an annoymous, Color's subtype class. GREEN overrides the public method.


Correct

Helen Ma wrote:In case2, the GREEN class does not override the private method in Color because private method cannot be overriden. GREEN has it own public method.
However, in the main method, GREEN.method() actually refers to the private method because GREEN is a Color and GREEN can "see" the private method.


Here GREEN is still an anonymous subclass of Color which defines a public method method (accidentally with same name as a private method in base class), and as you know: "you can only override a method if you inherit it" and private methods are not inherited. Because the reference variable type of GREEN is Color (which refers to an instance of an anonymous subclass of Color which defines a public method) you can only invoke methods of the Color type (which in this case is only the private method method). The public method method defined in the anonymous subclass of Color can never be used.
 
Cyril Sadasivan
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roel De Nijs wrote:...and private methods are not inherited


This statement needs correction. Private members are not inherited as long as they are not visible. Since an inner class has access to private members of outer class. An inner class extending an outer class inherits private members of the outer class. And that's the very basis of the code in this thread. However they cannot be overriden, just like how instance variables or static members cannot be overriden by design. An attempt to override a private method just creates a new method with the same signature. At compile time, the method to be invoked is decided by the type of reference used.

Helen Ma wrote:..and GREEN can "see" the private method.


Maybe you think that private method of class Color shouldn't be visible outside class Color. But that's not the case. Private members of an inner class are actually private to the outer most class. Thus private method of inner class Color is visible throughout class Main.
 
Helen Ma
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Thus private method of inner class Color is visible throughout class Main.



Hi, I don't see any private method of inner class Color in the example. Are you talking about the GREEN object? GREEN anonymous object has a public method, not private method. The private method belongs to Color, not the anonymous object.
To my understanding, GREEN anonymous object can see the private method, and it has another public method. The public method is not overridden. In the Main method, Color.GREEN.method() is actually refering to the private method.
 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Cyril Sadasivan wrote:An inner class extending an outer class inherits private members of the outer class. And that's the very basis of the code in this thread. However they cannot be overriden,


In my opinion the private members are not inherited (because otherwise you could override these private methods), but they are visible and thus accessible to the inner class.

Example:


Removing private access modifier (or changing it into protected/public) of doIt-method (of Outer class) results in inheritance and overriding the doIt-method in Inner class.
 
Roel De Nijs
Sheriff
Posts: 11606
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Helen Ma wrote:I don't see any private method of inner class Color in the example.


He meant the static nested class Color (which resides in Main class, hence "inner class")
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic