• 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

Q: Why can't I inherit from a public inner class from a diffrent package.

 
Mo Bustany
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is the parent class (inner class).

And here is the subclass (in a different package.

I get the error:

What does it mean 'not in scope'!!!
[ Jess adjusted line break in the code so the page won't overflow ]
[ February 06, 2003: Message edited by: Jessica Sant ]
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This works though:

I've still got to workout why yours doesn't.
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So does this:
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is this any nearer?
[ February 06, 2003: Message edited by: Barry Gaunt ]
 
Mo Bustany
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Barry, could you tell me what java 'rule' does my original code violates?? It looks to me it's syntactically correct.
 
Valentin Crettaz
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Since AccessControl.Car is not declared static you must have an instance of AccessControl in order to create an instance of AccessControl.Car.
You can remedy to this by declaring the class Car static, I guess. Try it out and let us know
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mo Bustany:
Barry, could you tell me what java 'rule' does my original code violates?? It looks to me it's syntactically correct.


I wish I knew what rule, Mo, I'm just fumbling around here. I do not fully understand inner classes yet, I got to read some more.
-Barry
 
Valentin Crettaz
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The rule is that you cannot instantiate a non-static inner class without already having an instance of the enclosing class. If you come to think about it, it makes sense. For instance, you cannot invoke instance methods or access instance member fields of class A without having an instance of the class A. A non-static inner class is just another instance member of the enclosing class, and thus, needs that the enclosing class be instantiated in order to exist.
Check out JLS 8.1.2 Inner Classes and Enclosing Instances for more details.
 
Dan Culache
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mo,
What Barry and Valentin said is right to some extent but you don't have to enclose BMW in a class that extends AccessControl. You don't have to have an instance of the enclosing/outer class like with the instance variables BUT in order to instantiate your class which is an inner class (because it extends an inner class) the compiler needs to call the constructor of the enclosing class, in your case AccessControl. The syntax might seem a little strange but I guess this is what you wanted.
See the code samples below:

and next I'm extending your inner class in a different package.

Making an extension of BMW in an outer class is trivial.

[ February 08, 2003: Message edited by: Dan Culache ]
[ February 08, 2003: Message edited by: Dan Culache ]
[ February 08, 2003: Message edited by: Dan Culache ]
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dan, I verified your code, it works a treat.
But why did Mo get the original compile error message:

???
I got it too when I compiled Mo's code.

[ February 08, 2003: Message edited by: Barry Gaunt ]
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dan said:

the compiler needs to call the constructor of the enclosing class, in your case AccessControl.


It's that new AccessControl().super() ; in the constructor that does the trick?
Back to the books...
-Barry
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So the compiler is really complaining because it cannot create the default no-arguments constructor (dnoac)?
The dnoac of BMW must call super() as its first statement. But its superclass AccessControl.Car is an inner class. So we must make an AccessControl object first: that's the new AccessControl() bit.
Now we can call the super() on it: new AccessControl().super();
Ho humm, this is going to take a bit of time to sink in...
Thanks Dan for muddling my world a little more
-Barry
PS Yup, adding the dnoac with that dinky little new AccessControl().super() fixes things. Gives me the goosebumps, this stuff.
[ February 08, 2003: Message edited by: Barry Gaunt ]
 
Dan Culache
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, it's the new AccessControl().super(); that "does the trick" as you say. The compiler only knows to insert a simple super(); so you have to teach him(I always picture the compiler as a guy, he's so rude and insensitive sometimes).
This way you create an "implicit/non-referenced" instance of AccessControl. "Implicit" but still an instance since you call new. This is where I didn't agree with Valentin. You can create an instance of a non-static inner class "without already having an instance of the enclosing class" by implicitly creating this instance inside the constructor. I guess it's just the wording...
Hope I was clear.
[ February 08, 2003: Message edited by: Dan Culache ]
 
John Paverd
Ranch Hand
Posts: 115
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dan

I had no idea you could could create the outer class in the constructor like that. Thanks!
Before I read this, I thought that I had to pass an outer super class reference to the constructor:
BMW(AccessControl ac) {
ac.super();
System.out.println("BMW constructor extending an inner class from another package");
}
 
Dan Culache
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
More than one way to skin a cat John!
But in terms of encapsulation and coding effort it wouldn't be very elegant, especially for a slick language like Java, to always have to define the constructor, instantiate the outer class, pass it to the constructor, etc.
I'm glad I could help.
 
Valentin Crettaz
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You don't have to have an instance of the enclosing/outer class like with the instance variables BUT in order to instantiate your class which is an inner class (because it extends an inner class) the compiler needs to call the constructor of the enclosing class,
And what does it mean to call the enclosing class' constructor? Already having an instance of the enclosing class or calling the enclosing class' constructor is exactly the same Anyway...
This is where I didn't agree with Valentin. You can create an instance of a non-static inner class "without already having an instance of the enclosing class" by implicitly creating this instance inside the constructor. I guess it's just the wording...
May well be the wording, I admit, but the effect is the same. Calling super() creates an instance which is implicitely at your disposal afterwards. To me, it is the same as having an explicit instance.
[ February 10, 2003: Message edited by: Valentin Crettaz ]
 
Dan Culache
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well since you opened the subject let's discuss it. I also have a question related to the matter.
Valantin, first you said:


The rule is that you cannot instantiate a non-static inner class without already having an instance of the enclosing class. If you come to think about it, it makes sense. For instance, you cannot invoke instance methods or access instance member fields of class A without having an instance of the class A.


to me "already" sounds like you implied one needs an existing instance of the outer class, something created and passed to the inner class constructor like John suggested above.
Then you said:


Already having an instance of the enclosing class or calling the enclosing class' constructor is exactly the same


In my opinion it is NOT exactly the same or I didn't know how to prove it.
If you "already" had an instance of the outer class you could access it's instance variables, right? I couldn't do it in the case I was talking about. See the code below and if you can access the variable of the outer class I agree, it's "exactly" the same. Again, maybe I didn't know how but if you cannot, you have to agree it is not "exactly" the same, OK?
 
Valentin Crettaz
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
to me "already" sounds like you implied one needs an existing instance of the outer class, something created and passed to the inner class constructor like John suggested above.
Well, not necessarly. When I say that an instance must already exist, I mean that the instance must exist when the constructor of the inner class is invoked. That is, in the following expression
new Outer().new Inner()
when the constructor of the inner class Inner is invoked, an instance of the outer class Outer already exists since it has just been created with a class creation expression.
That's what I meant and I admit that I should have expressed my thoughts in a much more clear manner, my apologies
 
Dan Culache
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I might be too picky but then you said:


Calling super() creates an instance which is implicitely at your disposal afterwards. To me, it is the same as having an explicit instance.


and this is where I didn't agree. That instance, even in your example is not at your disposal anymore. It would be interesting to know what the garbage collector does about that since both the instance in your example and the instance in mine are not referenced. I guess the relationship between the inner class and the outer class is preventing the gc from collecting the instance of the outer class?!
And about my pickiness, I apologize but I just want to thoroughly understand the language, that's why I try to clarify any ambiguity. Just like the compiler and you're not angry with the compiler, are you?
[ February 10, 2003: Message edited by: Dan Culache ]
 
Valentin Crettaz
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It would be interesting to know what the garbage collector does about that since both the instance in your example and the instance in mine are not referenced.
In fact it is. There is an implicit "this" (referencing the current object) as well as an implicit "super" (referencing the super class object) reference variable within every class.
I apologize but I just want to thoroughly understand the language,
...which is perfectly legitimate
Just like the compiler and you're not angry with the compiler, are you?
Never was and will never be
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic