Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Outer-Inner Question

 
Oliver Grass
Ranch Hand
Posts: 65
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi folks,
i just saw a little piece of code, which is interesting...
Wut happens when compiling and running the following prog

have fun
Oliver
 
Girish P
Greenhorn
Posts: 7
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As expected the code does not compile complaining about the statement print(1);
If you change the statement to OuterTest.this.print(1);It works fine.
I think this is what is expected.
 
deekasha gunwant
Ranch Hand
Posts: 396
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Girish and all,
i thought that all the methods of the enclosing class are available to the non static inner class.
but this program gives error for accessing print(1).
Girish or anybody else can u pls elaborate on why method print(1) is not accessible in Innerlass.

regards
deepti

 
Suresh Selvaraj
Ranch Hand
Posts: 104
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
A non-static Inner class can access both static and non-static methods or variables of the enclosing Outer class.
The code is perfectly correct except that the print(1) method in Inner class tries to invoke the print(1) method within the Inner class. Since there is no print() method that accepts one argument in the Innerclass i.e, print(1), a compile-time error occurs.
The correct way to access the print() method of the OuterTest class that takes one argument is,
OuterTest.this.print(1);
On replacing the print(1) in Inner class by "OuterTest.this.print(1);", the code copiles and gives the Output
Inner.print()
print()
print(int)
As explained earlier, the statement print(1) in Inner class invokes/expects a print(1) method within the show() method of the Inner class.
Here is the code.
public class OuterTest
{
void print()
{
System.out.println("print()");
}

void print(int i)
{
System.out.println("print(int)");
}


class Inner
{

void print()
{
System.out.println("Inner.print()");
}

// Added new print() method that takes a single int argument.
void print(int x)
{
System.out.println("Inner.print(x)");
}

void show()
{
print();
OuterTest.this.print();
// OuterTest.this.print(1);
print(1);
}
}

public static void main(String[] args)
{
OuterTest.Inner test = new OuterTest().new Inner();
test.show();
}
}
The Output of this code is :
Inner.print()
print()
Inner.print(x)
- Suresh Selvaraj
 
Nasir Khan
Ranch Hand
Posts: 135
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear deekasha
I think all the methods of the enclosing class are available to the non static inner class without "outer.this.methodname()" if they are not defined in inner.
In the above code print(1) gives error because compiler finds a method print() in the inner class but can't find the parameter of int type.
you can fix the problem as suggested by Girish or like this
public class OuterTest {
void print(){
System.out.println("print()");
}
void printg(int i){
System.out.println("print(int)");
}
class Inner {
void print(){
System.out.println("Inner.print()");
}
void show() {
print();
OuterTest.this.print();
printg(1);
}
}
public static void main(String[] args){
OuterTest.Inner test = new OuterTest().new Inner();
test.show();
}
}

 
saran_dd
Greenhorn
Posts: 3
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hai Friends,
According to Method Overloading technique, in inner class you do not have method overloading because you have only one print method. You can access all methods from outer class but before it will check the inner class method overloading and calling method. Method overloading is checked in compile time.

------------------
D.Saravanan,
Software Engineer,
Birla Consultancy & Software Services,
Mumbai.
 
dave taubler
Ranch Hand
Posts: 132
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay, now take this code:
<pre>
public class OuterTest {
void print(){
System.out.println("print()");
}
void print(int i){
System.out.println("print(int)");
}
void newPrint(int i) {
System.out.println("newPrint()");
}
class Inner {
void print(){
System.out.println("Inner.print()");
}
void show() {
print();
OuterTest.this.print();
newPrint(1);
}
}
public static void main(String[] args){
OuterTest.Inner test = new OuterTest().new Inner();
test.show();
}
}
</pre>
The difference is that I've added a <code>newPrint(int i)</code> method to the Outer class and now, instead of calling <code>print(1)</code> in the show() method, I call <code>newPrint(1)</code>. This compiles and runs fine.
So it seems that the combination of overloading & "inheritance" doesn't work the same way with Inner classes as it does with subClasses.
 
Scott Appleton
Ranch Hand
Posts: 195
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interesting. So am I correct in concluding that if you have an overloaded method in an outer class, all permutations of the overloaded method will be shadowed by a single implementation of that method in the inner class?
[This message has been edited by Scott Appleton (edited May 17, 2001).]
 
mousami bhattacharya
Ranch Hand
Posts: 40
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Can any one give a plausible explaination of why this happens as phrased by Scott.
Why doen't the inner class undertand the overloaded methods in the parent,if we give one implementation method of the same name
Rgs
M
 
sajida kal
Ranch Hand
Posts: 89
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is a very puzzling question indeed . I have tried the JLS to see if this can be explained by the compile time rules of method accessibility and invocation, but that did not really help. The behaviour does seems inconsistent in case of inner classes as Scott as summed up.
Could any of the moderators explain how the compiler treats this, taking us through this step by step ? This gets curiouser and curiouser by the minute!
Cheers,
Sajida
 
Cindy Glass
"The Hood"
Sheriff
Posts: 8521
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Note that the inner class is NOT a SUBCLASS of the outer class? That is the only way that methods get overridden. If you make this Inner class extend OuterTest then it can get at the print(i) just fine.
An inner class can get at the STATE of the outer class, it's instance variables, with no problem. An inner class can get at the methods of an outer class (that it does not shadow) by inheriting them, but there is no overriding going on.
The rules about signatures and overriding are not the same for inheriting without overriding. If the inner class could inherit some methods from the outer class, and then it names a member with the same name (note: this does not say "same signature"), then you have shadowed the name, and you do not inherit any of the stuff that you could have from the outer class OR the outer classes super classes.
(A member class includes local classes (in methods), anonymous classes, and non-static inner classes like above).
From the JLS 8.5 Member Type Declarations

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.

In this case because there is no Subclassing going on, the method print() shadows the 2 methods in the Outer class.

[This message has been edited by Cindy Glass (edited May 18, 2001).]
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic