Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / September 2007

Tip: Looking for answers? Try searching our database.

When a class doesn't know it's grandpa...

Thread view: 
Andreas Leitgeb - 06 Sep 2007 10:05 GMT
I'm somewhat surprised by a behaviour I didn't expect.

The situation is as follows:
 class Z.A  is static private and defines static meth().
 class Z.B is static public and inherits class Z.A.
 class Y inherits class Z.B, and shouldn't be able to
             know it's own grandpa Z.A.
But still, Y can call its grandpa's  static meth().

SSCCE: Z.java:  (but run class Y)
public class Z {
  private static class A {
     public static void meth() {System.out.println("Hello, World! A"); }
  }
  public static class B extends A { }
}
class Y extends Z.B {
  public static void main(String[]a){ Y.meth(); }
}
Piotr Kobzda - 06 Sep 2007 10:48 GMT
> I'm somewhat surprised by a behaviour I didn't expect.
>
> The situation is as follows:
>   class Z.A  is static private and defines static meth().

But that method is public, thus it's still publicly accessible.

>   class Z.B is static public and inherits class Z.A.
>   class Y inherits class Z.B, and shouldn't be able to
>               know it's own grandpa Z.A.
> But still, Y can call its grandpa's  static meth().

Declare meth() private to make it inaccessible outside the Z class.
Alternatively, if access to this method from other classes of your
package is desired (e.g. form Z.B) make it protected, or package
protected (which BTW, is usually a better choice than making it private
-- no synthetic accessors generation is needed).

piotr
rossum - 06 Sep 2007 11:37 GMT
>I'm somewhat surprised by a behaviour I didn't expect.
>
[quoted text clipped - 15 lines]
>   public static void main(String[]a){ Y.meth(); }
>}
Can you run class Y when Y is not public?

Do you need to use B.meth() anywhere?  If not then you could override
meth() inside B to throw an UnsupportedOperationException so the
version inherited by Y does not do anything useful?

 public static class B extends A {
   public static void meth() {
     throw new UnsupportedOperationException();
   }
 }

If you need to use meth inside B itself then you could use
super.meth() to pick the working version in A.

rossum
Ben Phillips - 06 Sep 2007 22:05 GMT
>>     public static void meth() {System.out.println("Hello, World! A"); }

> Do you need to use B.meth() anywhere?  If not then you could override
> meth() inside B to throw an UnsupportedOperationException so the
> version inherited by Y does not do anything useful?

Override a static method? That would be a neat trick. :)

You can *hide* it, of course...
Andreas Leitgeb - 14 Sep 2007 15:35 GMT
> Can you run class Y when Y is not public?
It did work, when I tried it :-)

For the rest of the posting:
sorry, that was irrelevant due to me not having
explicitly explained my "problem" well enough.
Roedy Green - 28 Sep 2007 01:11 GMT
>For the rest of the posting:
> sorry, that was irrelevant due to me not having
> explicitly explained my "problem" well enough.

for another explanation see
http://mindprod.com/jgloss/gotchas.html#OVERRIDE
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green - 06 Sep 2007 13:41 GMT
>  class Y inherits class Z.B, and shouldn't be able to
>              know it's own grandpa Z.A.
>But still, Y can call its grandpa's  static meth().

Just as you mother might intervene to pass gifts on from your
grandmother, you can do the same in Java.

Mother can preserve the original grandmother method by wrapping it in
a name like "grannysOrginialRecipe" then the child can access it.
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Andreas Leitgeb - 06 Sep 2007 23:04 GMT
>>  class Y inherits class Z.B, and shouldn't be able to
>>              know it's own grandpa Z.A.
>>But still, Y can call its grandpa's  static meth().
>
> Mother can preserve the original grandmother method by wrapping it in
> a name like "grannysOrginialRecipe" then the child can access it.

If she did that, I'd be less surprised. But mother's class-file doesn't
contain any mention of meth(), nor does granny's alter ego's classfile
(Z$1.class) have one.

The reason behind this thread lies in the dependencies-thread.
I wanted to know, whether private nested classes could have
any impact on other classes. While they can be seen only by
roommate(nested in the same place)classes, any of these might
expose them to public.
The result was: yes, they can, if any of their derivatives
goes public. So even methods of private classes need to be
taken care of (when they're added or removed).
Ben Phillips - 07 Sep 2007 01:17 GMT
> The result was: yes, they can, if any of their derivatives
> goes public. So even methods of private classes need to be
> taken care of (when they're added or removed).

When the methods aren't themselves private, anyway.

Private methods can be changed without worrying about direct effects
outside the one source file.

Private classes with package-private methods "leak" the least after
that. Private classes with no non-private descendants in the same source
file should be as safely changeable as private methods. That an instance
might be returned (e.g. from a factory method) and used by an outsider
doesn't change this since there are intermediaries. Like a public method
calling a private method and needing to change if the private method
changes, if this private class changed the method that returned an
instance might need to change, or the interface type that was the return
type might need to change.

That said, it's probably a wart in the JLS that it's permitted for a
non-private class to extend a private class that has public methods.
It's certainly poor encapsulation to have such an arrangement in your
code. Often it's a sign of having used inheritance where composition
would have been the better choice, as is the case in pretty much all
situations where an inherited method is exposed that you feel should not
be exposed. Always consider that an alert that composition is to be
considered as an alternative to the inheritance that is bringing in the
unwanted public method.
Andreas Leitgeb - 14 Sep 2007 16:17 GMT
>> The result was: yes, they can, if any of their derivatives
>> goes public. So even methods of private classes need to be
>> taken care of (when they're added or removed).
> When the methods aren't themselves private, anyway.
> Private methods can be changed without worrying about direct effects
> outside the one source file.

Thanks, and sorry for my lateness in answering...
Your posting put my mind back on the right track on
that topic. Java's behaviour now looks more natural
to me than before.

To close up this thread, yet another screwed example:
(no need to followup, unlike you really want to)

---- snip --- Z.java ---
public class Z {
  private void meth() {
        System.out.println("Hello, World! Z");
  }

  public static class A extends Z {
     public void meth(int i) {  // this is *not* an override!
        // puzzle: which of the following three lines of code are
        //  compileable, and which cause an compiler-error?
        //  guess first, try then (unless you know it anyway).
        meth();
        Z.meth();
        super.meth();
        // 'nother one: if these methods were both static,
        //  which of the previous lines would then be compileable?
     }
  }
}
class Y {
  public static void main(String[]a){ new Z.A().meth(1); }
}
---- snip --- EOF ---


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.