aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes super() call in inner classes Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "super() call in inner classes" Watch "super() call in inner classes" New topic
Author

super() call in inner classes

Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Taking into account he following two cases:
A)
class P {
class S {
}
}

class C extends P.S{
C () {
new P().super();
//here is necessary a qualified super() in order to call constr. P.S}
}
}
and
B)
class P {
class S {
}
}
class O extends P {
class C extends P.S {
C () {
super(); //new P().super() is ok also new O().super(), since O is a sublass of P
//here is OK an unqualified or qualified super() in order to call constr. P.S
}
}
}
I do not understand why the case below compiles and calls the constructor of P.S when I use the unqualified super() call, since now there is a class S in Class O which hides the class S in P!!!
class P {
class S {
}
}
class O extends P {
class S { // hides P.S
}
class C extends P.S {
C () {
super(); // new P().super() is ok also new O().super(), since O is a sublass of P
}
}
}
Can someone please explain me in detail what happens in this case...


"Did anyone understand what I have just explained? ... because I did not!"
Narasimha Rao B.
Ranch Hand

Joined: Aug 26, 2002
Posts: 205
Hi Dan,
Really i could not understand what you have told. But it seems really interesting. Hence can you give me for all the three examples working code.
Hence i can practice the same.
Thanks a lot for posting a nice thing.


Narasimha
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Hi
well I can give you the code for last case with the constructors inserted:
the first two cases are based on the last one which I do not understnad why
it works, I think the comments in the first two cases are helpfull also.

class P {
P(){System.out.println("P");}
class S {
S(){System.out.println("P.S");}
}
}
class O extends P{
O(){System.out.println("O");}
class S { // hides P.S
S(){System.out.println("O.S");}
}
class C extends P.S {
C () {
super();//calls P.S constructor
System.out.println("C");
}
}
}
class Test8851{
public static void main (String args[]){
O oo =new O();
O.C cc= oo.new C();
}
}
Why when I run this the unqualified call from super() in class C calls constrcutor P.S, because class P.S is now hidded in class O
Please tell me if there any other ambiguities
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Sorry I did not finish my last sentence:
Why when I run this the unqualified call from super() in class C calls constrcutor P.S, because class P.S is now hidded in class O , I DO NOT understand how this works
Please tell me if there any other ambiguities
Narasimha Rao B.
Ranch Hand

Joined: Aug 26, 2002
Posts: 205
Thanks a lot Dan.
Now the code you have given is working fine, now i am going through that one. I will get back you, with my thoughts, once after going through the same.
Thanks,
Bojan Knezovic
Ranch Hand

Joined: Nov 20, 2003
Posts: 90

You're extending the class S that resides in in class _P_ not the class S that resides in O.
Your comment in code

tells me that, or at least I think so, you're confused. Class S inside class O can't hide the class S in class P. Because the first one, simply put is O.S and the other one O.P.S (think encapsulation!).
If I'm mistaken, correct me please.

HTH,
Bojan
[ February 29, 2004: Message edited by: Bojan Knezovic ]
Bojan Knezovic
Ranch Hand

Joined: Nov 20, 2003
Posts: 90
Originally posted by Bojan Knezovic:

I'm not sure I fully understood you...
You're extending the class S that resides in in class _P_ not the class S that resides in O.
Your comment in code

tells me that, or at least I think so, you're confused. Class S inside class O can't hide the class S in class P. Because the first one, simply put is O.S and the other one O.P.S (think encapsulation!).
If I'm mistaken, correct me please.

HTH,
Bojan
[ February 29, 2004: Message edited by: Bojan Knezovic ]

P.S. It seems that this "edit" option has some kind of bug - it ate a part of my post!
Narasimha Rao B.
Ranch Hand

Joined: Aug 26, 2002
Posts: 205
Hi,
What is meant by qualified constructor call and unqualified constructor call.
Thanks
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Hi Bojan,
"tells me that, or at least I think so, you're confused. Class S inside class O can't hide the class S in class P. Because the first one, simply put is O.S and the other one O.P.S (think encapsulation!).
If I'm mistaken, correct me please."
the other one is P.S not O.P.S. (this for the case when S is an inner class of P which in turn is an inner class of O)
Class S from S is INHERITED in class O.
also from JLS 2.0 chap. 8.5:
"If the class declares a member type (CLASS IN OUR CASE) with a certain name, then the declaration of that type is said to hide any and all accessible declarations of member types with the same name in superclasses and superinterfaces of the class."
try using new O().super() and new P().super() in class C and you'll get the same result, because O is a subclass of P.
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Hi Narasimha,
to beter understand what I'm talking about see the link below:
http://www.ergnosis.com/java-spec-report/java-language/jls-8.8.5.1-a.html
qulified is new O().super()
unqualified is just super();
Bojan Knezovic
Ranch Hand

Joined: Nov 20, 2003
Posts: 90
Originally posted by Dan Andrei:
Hi Bojan,
"tells me that, or at least I think so, you're confused. Class S inside class O can't hide the class S in class P. Because the first one, simply put is O.S and the other one O.P.S (think encapsulation!).
If I'm mistaken, correct me please."
the other one is P.S not O.P.S. (this for the case when S is an inner class of P which in turn is an inner class of O)

Well, the other one *IS* P.S but since the O extends P, then it's O.P.S inside class O.


Class S from S is INHERITED in class O.

I must admit that I didn't quite get this.


try using new O().super() and new P().super() in class C and you'll get the same result, because O is a subclass of P.


As far as I get it all, it can't be the same - O extends P, so its superclass is P, while P doesn't extend anything (OK, it extends Object implicitly but that doesn't matter now) so it won't have any constructor to call.

Bojan
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Bojan, lets look at it step by step, and look at the comments please:
first:
class P {
class S {
}
}

class C extends P.S{
C () {
new P().super();
//here is necessary a qualified super() in order to call constr. P.S}
}
}
second:
class P {
class S {
}
}
class O{
class C extends P.S{
C () {
new P().super();
//here is necessary also a qualified super() in order to call constr. P.S
// regardless of the fact that class O is enclosing class C
}
}
}
third:
// now class O extends P
class P {
class S {
}
}
class O extends P {
class C extends P.S {
C () {
super(); //new P().super() is ok also new O().super(), since O is a
//sublass of P
//here super() is OK since O extends P so class S is a memeber of O
// and is not neccessary anymore to use to create the enclosing instance of the superclass S (in this case P)
}
}
}
fourth:
//a class S is now defined in class O which hides class S in P:
class P {
class S {
}
}
class O extends P {
class S { // hides P.S
}
class C extends P.S {
C () {
super(); // new P().super() is ok also new O().super(), since O is a sublass of P
}
}
}
Now I do not understand why in this case the simple call to super() still works since now class S is hidden so is not inherited in O.
Is my problem clearer now ?
Bojan Knezovic
Ranch Hand

Joined: Nov 20, 2003
Posts: 90
Originally posted by Dan Andrei:
Now I do not understand why in this case the simple call to super() still works since now class S is hidden so is not inherited in O.


To be perfectly honest, I can't check your code right now - too tired, too much reading. I'll do it in the morning.
Just wanted to tell you that I think the class IS INHERITED, but might be it's being "shadowed" by the local class. If it makes sense drop me a note, but I'll still check it out in the morning like I said.
'night.
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Well shadowind is different from hiding:
this is from JLS 2.0 , chap 8.5:
"If the class declares a member type with a certain name, then the declaration of that type is said to hide any and all accessible declarations of member types with the same name in superclasses and superinterfaces of the class.
Within a class C, a declaration d of a member type named n shadows the declarations of any other types named n that are in scope at the point where d occurs."
Also from JLS 2.0:"
"Note that shadowing is distinct from hiding. Hiding, in the technical sense defined in this specification, applies only to members which would otherwise be inherited but are not because of a declaration in a subclass."
Second, there is no LOCAL class here, is an INNER CLASS!
Third, to check my program you can use one of my prevoius posts, where I inserted contrs. with prints stats.
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Please read previous post also
Here is the program with the constr. inserted:
class P {
P(){System.out.println("P");}
class S {
S(){System.out.println("P.S");}
}
}
class O extends P{
O(){System.out.println("O");}
class S { // hides P.S
S(){System.out.println("O.S");}
}
class C extends P.S {
C () {
super();//calls P.S constructor
System.out.println("C");
}
}
}
class Test8851{
public static void main (String args[]){
O oo =new O();
O.C cc= oo.new C();
}
}
Bojan Knezovic
Ranch Hand

Joined: Nov 20, 2003
Posts: 90
OK, I have seen the last piece of code that you posted and all I can say is that I don't understand what's wrong - it returns what I expected:

returns

P
O
---
P.S
C


If class C was to extend O.S, the output would've been different:


P
O
---
O.S
C


Again, quite understandable.
What I'm trying to tell you is that by OO principles (or at least by the principles they taught me in the U days), inner class S inside the class O that extends P CANNOT hide the class S in P.S like you said in your comment:


As I said before, one is S inside O the other one is S inside P, although the O extends P it doesn't matter - it's not like that by extending something it will be at the same "level" as if you declared it directly in your extending class (simply put it's not the same). There's that additional level of encapsulation and because of it your class S in O can't hide the class S in P.

Take a look at this for example:

The method b.getX() is working flawlessly but the class B obviously doesn't have the member int x - how come?
Because there's that additional capsule I've been talking about. Now, apply this to your example and I hope it will be clearer why you get the output you get.

Bojan
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
Please take a look at the following link this is where a got the example from:
http://www.ergnosis.com/java-spec-report/java-language/jls-8.8.5.1-a.html
My problem is that I DO NOT understand HOW this wotks in this case,
when S is hidden, in my opinion it sould work only when calling
new P().new S() or new O().new S()
You example is not exactly like mine, take a look at this one and replace variables by class declaration and look at the explnantion below which is from JLS
class Point {int x = 2;}
class Test extends Point {double x = 4.7;}
"because the declaration of x in class Test hides the definition of x in class Point, so class Test does not inherit the field x from its superclass Point. It must be noted, however, that while the field x of class Point is not inherited by class Test, it is nevertheless implemented by instances of class Test. In other words, every instance of class Test contains two fields, one of type int and one of type float."
Both fields bear the name x, but within the declaration of class Test, the simple name x always refers to the field declared within class Test
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
This is a continuation of my post above
...
I want to make a cooment on your statement:
"As I said before, one is S inside O the other one is S inside P, although the O extends P it doesn't matter "
Well it matters a lot that O extens S since this is why you can use a call
like super() (unqualified call ), if O does not extend S and you try super()
youl'll get a compile error (look at my step by step example), the only way it works in this case is:
new S().new C() OR new O().new C().
Bojan Knezovic
Ranch Hand

Joined: Nov 20, 2003
Posts: 90
Originally posted by Dan Andrei:

class Point {int x = 2;}
class Test extends Point {double x = 4.7;}
"because the declaration of x in class Test hides the definition of x in class Point, so class Test does not inherit the field x from its superclass Point. It must be noted, however, that while the field x of class Point is not inherited by class Test, it is nevertheless implemented by instances of class Test. In other words, every instance of class Test contains two fields, one of type int and one of type float."


Wouldn't want to go against the JLS but can't quite agree on this one. First of all it's not very clear:
1) "class Test does not inherit the field x from its superclass "
2) "every instance of class Test contains two fields, one of type int and one of type float"
If it's not inherited, how can it exist in an instance of the class? I'd say that #1 is not very well phrased.
If we modify my previous example:


If you execute it, you'll see that getX() still returns 1. Because it's executed in the "environment" (=capsule) of class A inside class B. To my opinion, this shows that x from superclass is ALWAYS inherited.

Both fields bear the name x, but within the declaration of class Test, the simple name x always refers to the field declared within class Test

Exactly!
Now apply that to your example, when you say

C's superclass will be class S inside P and NOT class S inside O.

My problem is that I DO NOT understand HOW this wotks in this case,
when S is hidden, in my opinion it sould work only when calling
new P().new S() or new O().new S()

But why?? Why should S be hidden?? Classes C and S are at the same "level" and besides P.S can NEVER NEVER be the same as O.S...
Dan Andrei
Ranch Hand

Joined: Jan 21, 2004
Posts: 92
First I want to make a small correction to one of your posts:
“If we modify my previous example:
code:

class A {
private int x=1;
public int getX(){
return x;
}
}
public class B extends A{
private int x=2;
public static void main(String[] args) {
B b=new B();
System.out.println(b.getX());
}
}

If you execute it, you'll see that getX() still returns 1. Because it's executed in the "environment" (=capsule”of class A inside class B.
To my opinion, this shows that x from superclass is ALWAYS inherited."
This is from jls:
”Members of a class that are declared private are not inherited by subclasses of that class.” Jls chap 8.2
Also you use a helper class to get to member x o the superclass.
I also want to say that I got your point …
Things got crystal clear when I tried the case below where Class S is actually hidden:
class P {
P(){System.out.println("P");}
class S {
S(){System.out.println("P.S");}
}
}
class O extends P{
O(){System.out.println("O");}
class S { // hides P.S
S(){System.out.println("O.S");}
}
class C extends S {
C () {
super();
System.out.println("C");
}
}
}
class Test8851a{
public static void main (String args[]){
O oo =new O();
O.C cc= oo.new C();
}
}
with output:
P
O
O.S
C

I realise now that most of the confusion started when in the linked that I told you about the term “hidden “ is used rather loosely in my opinion.
Thanx for all you input and time Bojan
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: super() call in inner classes