• 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

Private class can't have public inner?

 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I may be misinterpreting an answer from Marcus Green's mock exam, but it appears that a private outer class cannot have a public non-static inner class. Is this true? Would this be because you have to create an instance of an outer class to get to a non-static inner class, and if it's private you couldn't get there from here? Any help would be appreciated.
------------------
 
Desperado
Posts: 3226
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
�Private outer classes...�
If by that you mean �package access classes�, then they can�t be private, static or protected.
 
BillLeighton
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So, to rephrase, if I have a class "Outter", and I want to created a non-static inner class within it, I better not declare "Outer" to be private, static or protected? Or is this only the case if I wanted to make the inner class "public"? Am I making sense or confusing the issue?
Perhaps what I am asking is there any access modifier constraints for "containing" classes with inner classes... thankd for your help!
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Regardless of what classes may be defined inside it, a regular top-level non-nested class cannot be static, private, or protedted. Period.
If "Outer" is instead some kind of nested class that has another class nested inside of it, then Outer can have any modifiers appropriate to the type of class it is (e.g. local classes can't be anything but final). The fact that it has another class defined inside it does not put any extra restrictions on the modifiers that I'm aware of.
If there's a specific example you're thinking of, try writing some sample code to see if it compiles.
 
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think what Bill may mean (and has me scratching my head as well) is that top-level classes may be "default" or public access while inner classes may be public, "default", protected, or public access (and I'm not talking television here).
If we assume:

What are we to make of the possible combinations of name1, name2, modifier1, modifier2, and modifier3? Is the "public" of an inner class like the "public" of an outer ("top-level") class or the "public" of a member field/method? The problem is that the one example I've seen for class User doesn't make it at all clear because all the modifiers were public:
Outer.Inner io = new Outer().new Inner(); // yuck!
If all the modifiers are public (and even if they are in different packages) or if all the modifiers are "default" (and in the same packages) then this works (not that you would want to do this very often). What about the other combinations? Do we need to know? Should we know?
IF the access modifier to an inner class works exactly like an access modifier to a class variable/method then it makes some sense. If the access modifier to an inner class is like the access modifier of an outer class then what do "protected" and "private" mean in this context? Then there are the weird questions...can you subclass an inner class? Override? Inherit? Can't we just use them for event handling and get on with our lives?
Steve
sgwbutcher@aol.com
[This message has been edited by Steve Butcher (edited March 21, 2000).]
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Access modifiers for nested classes work pretty much exactly the same as access modifiers for variables and methods (unless I'm forgetting something). It's only the access modifiers for top-level (non-nested) classes that are, ummm, different. For these top-level classes: Declaring a class public means that you have to name the file itself after the class, which makes it so the compiler can actually find the class. OK, that's useful. Declaring a class with no modifier (package access) means it's not visible outside that package. This can be convenient in that it allows us to put multiple classes in one file. But if you wanted to access them from another package, the compiler wouldn't know where to find them anyway since the file isn't named after them, and the compiler wouldn't want to search the contents of all files on the machine in the hope that it could find the class you've named. So, this use of package access also makes some sense and is useful. So public and package access have meaning for top-level classes, and the meaning centers around whether or no the file is named after the class inside. Given this - what use would "protected" or "private" be? What would they mean? I think the language designers never came up with a use or need for these modifiers for top-level classes, and so they forbod them.
In general then, modifiers for top-level classes are essentially independent from the modifiers for variables, methods, and nested classes contained within. They mean different things. You may wonder, for example, what use it could possibly be to have a public method inside a package-access class. Who else is ever going to see it after all? But in fact, it's possible that instances of your package-access class can be passed to other packages and files - it's just that these other packages and files know nothing of the class, so they can only use the instance if it's identified usinng a public base class or interface. Here's an example:

I hope this example makes sense; it's getting late and I may not be thinking straight. If not, you can ask me about it tomorrow.
[This message has been edited by Jim Yingst (edited March 21, 2000).]
 
Ranch Hand
Posts: 216
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think
Runnable r = A.handOff();
should be
Runnable r = PublicClass.handOff();
Jim am i correct or missing some thing.....
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oops! Good catch - you're right.
 
Steve Butcher
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jim,
(1) So basically you're saying that if package access class implements a public interface AND you can get a handle to an instance of it through a public class in that package, you may still want to declare various methods of it public so that the handle in the other package can do useful things with that object?
(2) Inner classes are like other class "members" and access modifiers operate accordingly. So in Bill's example, if a top level class had package access then even if it's inner class was public, you couldn't get to the inner class.
(3) I'm assuming based on this discussion that (a) inner classes are inherited but (b) they are not subclassable.
Steve
sgwbutcher@aol.com
PS [OT] if you want a separate thread shouldn't that be r.start()?[Ooops...I stand corrected; only the "don't call run() part stuck in my mind not that "from what" part]
PPS you can tell which chapters I've read and understood by which questions I answer and which questions I post
[This message has been edited by Steve Butcher (edited March 22, 2000).]
 
Jim Yingst
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Steve-
(1) Exactly. Also, even if you don't make the class instance available outside the package - if you wan to implement an interface such as Runnable for any reason, the interface methods have to be declared public or the compiler will balk. Even if you know they will only ever be used inside the current package, you still can't make the method less public than its initial declaration. (And note that interface methods are always implicitly public.)
(2) Right - not unless you are attempting to access the inner class from the same package. Or unless you provide an access method to get at an instance of the class as I showed - but the other packages still don't know anything about the inner class, only the public interface.
(3) They're inherited, yes (though if an inner class is private, you can't access it from subclasses). But they are subclassable from anywhere in the scope of the inner class. The only kind of nested class that isn't subclassable is an anonymous class, since there's no way to say what you're extending. (Who knows, there may even be a way to do that using reflection - but never mind that.) You don't see it done very often, as usually if a class is useful enough to bother extending, it's useful enough to make public so you can use it elsewhere. But in principle there's no reason you can't do it:
<code><pre> public void method() {
class LocalBase {}
class LocalSub extends LocalBase {}
}</pre></code>
I can't think of a good example offhand where it's actually useful. Maybe for static nested classes I suppose...
P.S. But I implemented Runnable, not Thread. So a new thread would be <code>new Thread(r).start()</code>. I was just constructing a minimal example though - it's not like the program was doing anything useful anyway.
 
Steve Butcher
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, but that's not true...it was teaching me the wily ins and outs of inner classes.
BTW, it makes perfect sense why an inner class cannot be subclassed out into an outer class but can be subclassed within its own scope...it can have references to the enclosing class...then where would you be?
Steve
sgwbutcher@aol.com
[This message has been edited by Steve Butcher (edited March 22, 2000).]
 
reply
    Bookmark Topic Watch Topic
  • New Topic