Author Topic:   Observations & questions about Inner...
jayesh bindra
greenhorn
posted July 16, 2000 04:55 PM             
Hi,
A couple of observations first...
1. Consider the following code
code:
interface Interface {
void someMethod();
}
class TestInterface1 implements Interface{
class Inner{
public void someMethod() {
System.out.println("someMethod");
}
}
public static void main(String args[]) {}
}

On compiling this code, the following error occurs
TestInterface1 should be declared abstract; it does not define someMethod() in TestInterface1
class TestInterface1 implements Interface{
^
1 error

2. Well everyone knows that one can have a class within another class, but not many people know that one can have an interface within a class. The following code proves this

code:
 class TestInterface2 {
public void method(){
System.out.println("Outer method");
Inner in=new Inner();
in.doNothing();
}
interface MyInterface {
void doNothing();
}
class Inner implements MyInterface {

public void doNothing() {
System.out.println("Inside doNothing");
}
}
public static void main(String args[]) {
new TestInterface2().method();
}
}



The code performs as expected.

Now for the questions
1. Why does code given in Observation 1 give out the error?
2. Consider the following code

code:
interface MyInterface {
void doNothing();
}
class TestInterface3 implements MyInterface {

public void doNothing(){
System.out.println("Outer doNothing");
Inner in=new Inner();
in.doNothing();
}
interface MyInterface {
void doNothing();
}
class Inner implements TestInterface3.MyInterface {

public void doNothing() {
System.out.println("Inside doNothing");
}
}
public static void main(String args[]) {
new TestInterface3().doNothing();
}

}



On compiling this code, a error is generated. Error could have been expected, but not the error that takes place!

cyclic inheritance involving TestInterface3
interface MyInterface {
^
1 error

cyclic inheritance?

What is happening here?
Thanks in advance,
Jayesh

sdev
ranch hand
posted July 16, 2000 06:31 PM         
Hi Jayesh,


code:
interface Interface {
void someMethod();}
class TestInterface1 implements interface{
class Inner{
public void someMethod() {

System.out.println("someMethod");
}

}
public static void main(String args [])
{}
}



Here the class TestInterface1 implements an Interface but it is not implementing the method of an interface. Class Inner is an inner class for TestInterface1 and this class is not needed to implement an interface as per the rule.

So, the TestInterface1 must be abstract and class Inner must implement an interface

Code should be like this:

code:

interface Interface
{ void someMethod(); }
abstract class TestInterface1 implements Interface
{
class Inner{
public void someMethod() {
System.out.println("someMethod"); }
}

public static void main(String args[])
{}
}


This below code works fine.Because class inner is implementing the method of an interface.

code:

interface MyInterface {
void doNothing();}
class TestInterface3 implements MyInterface {
public void doNothing(){
System.out.println("Outer doNothing"); Inner in=new Inner(); in.doNothing();
}
interface MyInterface {
void doNothing(); }
class Inner implements TestInterface3.MyInterface
{
public void doNothing() {
System.out.println("Inside doNothing"); }
}
public static void main(String args[]) { new TestInterface3().doNothing(); }}

This code gives error, because u are trying to override the interface inside a class.

Interfaces may not be overridden.


It may help u . If wrong please let me know...

sdev.

[This message has been edited by sdev (edited July 16, 2000).]

[This message has been edited by sdev (edited July 16, 2000).]

[This message has been edited by sdev (edited July 16, 2000).]

rahul_mkar
ranch hand
posted July 16, 2000 11:44 PM             
Hi Jayesh

try compiling the following code

class demo extends x { }
class x extends demo{}

what happens? what is the error? think.

in the default constructor of demo the default consructor of x is called. Now in the default constructor of x the default constructor of demo is called. a problem just like a stack overflow is likely to occur if this code is allowed to execute. The compiler through an algorith is however is able to detect this during compilation. It "Screams" stopping the program till the matter is resolved by the programmer. this is the Cyclic class inheritance error .

The code that u wrote is working fine for me and printing out OUter do nothing
inner do nothing

so i do not have an error!!. i have saved the file as TestInterface3.java

please check up again.

interface MyInterface
{
void doNothing();}

class TestInterface3 implements MyInterface {
public void doNothing(){
System.out.println("Outer doNothing");
Inner in=new Inner();
in.doNothing(); }
interface MyInterface {
void doNothing(); }
class Inner implements TestInterface3.MyInterface { public void doNothing() { System.out.println("Inside doNothing"); } } public static void main(String args[]) { new TestInterface3().doNothing(); }}

Regds.
Rahul

jayesh bindra
greenhorn
posted July 17, 2000 05:50 AM             
Hi sdev,
Let me state my question 2 a little more clearly. The question is not why the code is generating the error, but why this particular error is getting generated. See if we go by your interpretation that it is because interfaces may not be overridden then then the following error will be generated

duplicate class: DupInterface
interface DupInterface {
^
1 error

This error has been generated by the code given below

code:
interface DupInterface {
void someMethod();
}
interface DupInterface {
void someMethod();
}
class TestInterface implements DupInterface {
public void someMethod(){};
}

But in case of the code given before, it was

cyclic inheritance involving TestInterface3
interface MyInterface {
^
1 error

How is cyclic inheritence happening here?
Regards,
Jayesh.

jayesh bindra
greenhorn
posted July 17, 2000 05:54 AM             
Hi Rahul,
What platform are you working on?
I am working on Win98 + JDK1.3. The code is generating an error on it.
And I certainly know what cyclic inheretance is, but fail to understand how it is occurring here.
Regards,
Jayesh

[This message has been edited by jayesh bindra (edited July 17, 2000).]

sdev
ranch hand
posted July 17, 2000 07:34 AM         
Hi Jayesh,

Iam sorry , I didn't try to execute this program , as I just went through and got an idea like that. I am really sorry.

Now , I executed this program and I didn't get any errors.

code:

interface MyInterface {
void doNothing();
}

class TestInterface3 implements MyInterface {
public void doNothing(){

System.out.println("Outer doNothing");
Inner in=new Inner();
in.doNothing();
}


interface MyInterface {
void doNothing();
}
class Inner implements TestInterface3.MyInterface {

public void doNothing() {
System.out.println("Inside doNothing");
}
}// End of class inner

public static void main(String args[]) {

new TestInterface3().doNothing();
}
} // End of class TestInterface3


Thanks.. sdev.


[I had to break up one over-long line - Jim Y]

[This message has been edited by Jim Yingst (edited July 24, 2000).]

jayesh bindra
greenhorn
posted July 17, 2000 08:22 AM             
Hello sdev,
I cut-copy-pasted the code you had given(even though its the same as mine). It is still generating the error.
I am using JDK 1.3 on Win98. What are you using?
Confused,
Jayesh.
P.S. Could you also edit your post so that we dont have to use our horizontal scrollbar.

[This message has been edited by jayesh bindra (edited July 17, 2000).]

jayesh bindra
greenhorn
posted July 18, 2000 12:56 AM             
Hi,
Why is it that I am getting this error and they aren't?
Please help.
Regards,
Jayesh

Gaurav Chikara
ranch hand
posted July 18, 2000 01:15 AM             
Even I did not get any errors
in it
quote:
Originally posted by jayesh bindra:
Hi,
Why is it that I am getting this error and they aren't?
Please help.
Regards,
Jayesh

jayesh bindra
greenhorn
posted July 18, 2000 05:21 AM             
Gaurav, Sdev & Rahul,
Could you please state the version of JDK and the platform that you are using.
Thanks,
Jayesh

jayesh bindra
greenhorn
posted July 18, 2000 02:30 PM             
Guys/gals please help me out here. Please state you JDK version and platform.
Jayesh

hemanshow
greenhorn
posted July 18, 2000 02:49 PM         
No error.
NT 4
java version "1.2.2"
Classic VM (build JDK-1.2.2_005, native threads, symcjit)

rahul_mkar
ranch hand
posted July 18, 2000 09:50 PM             
hi,

sorry i was busy.

i am using windows 98 and jdk 1.2.2 .

hope this helps
Regds.

Rahul.

Gaurav Chikara
ranch hand
posted July 18, 2000 11:19 PM             

Windows 95 JDK1.2.2

quote:
Originally posted by jayesh bindra:
Gaurav, Sdev & Rahul,
Could you [b]please
state the version of JDK and the platform that you are using.
Thanks,
Jayesh[/B]

Ajit Arora
unregistered
posted July 19, 2000 02:51 AM           
Win 98
JDK1.3
getting the error.
Very surprising.
Ajit.

jayesh bindra
greenhorn
posted July 19, 2000 11:23 AM             
Hi all,
Thank you Ajit. I was beginning to think there was something wrong with my machine 'cause no one else seemed to be getting the error. Wouldn't it be nice if the moderaters were to step in. Hope Ajith, maha anna are listening for they can help us remove this confusion.
Thanks,
Jayesh

[This message has been edited by jayesh bindra (edited July 19, 2000).]

Sateesh Kumardid
unregistered
posted July 19, 2000 12:14 PM           

Even I

Sateesh Kumar
unregistered
posted July 19, 2000 12:15 PM           

Even On my computer it has n't produced any error.
It worked fine...

I have Win95 and JDK1.2.2.

maha anna
bartender
posted July 19, 2000 02:54 PM             
Hello all,
I tested the above code using jdk 1.2.2 on WIN98. It compiles and runs fine producing "Outer donothing" and "Inside donothing".

My observation is, I do not see any cyclic behaviour here in this code. We can always define interfaces in a .java program as a separate entity or inside a class definition. Any interface definition has its own scope. For example ,the outer interface has its scope as the "entire java program" and the inner interface defined inside the class defn. has its scope as the "whole class defn". So as long as we write the valid access code like "MyInterface " or the "TestInterface3.MyInterface", it is ok. Here in this code , inside the TestInterface3 class both of the above 2 access means SAME. Inside the TestInterface3 class defn we are writing a new interface defn which happened to have the same name as the outer interface name. ALso note that, in Java in inner class situations only ,we CAN NOT have an inner class name same as that of the enclosing class. Other than that we do not have any name writing restrictions. We can even have a variable/method name same as that of the classname inside which the variable/method with the same name is written.

Also all the other code snippets in the above program also fine and legal to code.

Jayesh,
I will check up in the "Bug Parade" of sun site to see anything reported for this kind of error for you. Also anything new explored by others also welcome.

regds
maha anna

[This message has been edited by maha anna (edited July 19, 2000).]

jayesh bindra
greenhorn
posted July 23, 2000 04:11 AM             
Hi,
Thanks a lot maha anna for your post. I am sorry, I could not respond earlier.
Anyhow, maha anna what did you find out? Is it a bug?
Regards,
Jayesh

Praveen Zala
greenhorn
posted July 24, 2000 12:30 AM         
Hi Jayesh and Maha Anna,
The code is working fine for me on JDK1.2.1 and WIN95......
Wonder why it gives errors in the other versions...
Praveen Zala

maha anna
bartender
posted July 24, 2000 03:40 PM             
Hello all,
I went to Sun's site and browse the 'Bug parade'. We have to log in first in order to access the Bug database. Registration is free. You all can use Maha's login id.

Login :mahaanna
password :selvi

After log in , use the search facility with the keyword 'cyclic'. I got 40 results. I browse through the links. There are SO MANY cyclic inheritance related errors reported. But I could not find ours. May be I did not see each link properly. So I request others to verify them, if it is not already reported, we can SUBMIT this bud as new bug.
Thanks for your co-operation.
regds
maha anna

Jim Yingst
sheriff
posted July 24, 2000 10:30 PM             
OK, I haven't worked through all the research yet, but it's late so I'll just post what I have so far. I hope this is coherent - I'm rushing it a bit at the last minute to get home.

First off, I weeded out the code that didn't seem to affect the error message, and got it down to this:


interface MyInterface { }

class Test implements MyInterface {
interface MyInterface { }
}

This compiles for 1.2.2 and earlier, but not 1.3.0, where it gives the error: "cyclic inheritance involving Test" at the line "class MyInterface {}". My guess is that in the line "class Test implements MyInterface" the compiler thinks that "MyInterface" refers to the nested interface MyInterface, rather than the top-level MyInterface previously defined. I think this because we get the exact same error message by deleting the first line:


class Test implements MyInterface {
Interface MyInterface { }
}

While the following compiles without error:


package mypackage;

interface MyInterface { }

class Test implements mypackage.MyInterface {
interface MyInterface { }
}

See, as long as the compiler knows you mean the top-level MyInterface, there's no problem.

Note also that if you replace each "interface" with "class" and each "implements" with "extends", you get the same result. (Except for the "class" in "class Test", which should remain the same.)

OK, the closest bug to this seems to be . Kind of similar, and they explain that under the JLS2, an interface may not "depend on itself". I eventually located what appear to be these rules, and . It's not yet clear to me whether these rules are being correctly applied by the JDK 1.3.0 or not. My gut reaction right now is that the JLS2 is ambiguous on these points. On the other hand, it shouldn't really be a problem for most of us - don't define a nested class or interface with the same name as a top-level class or interface in the same scope, and there shouldn't be any problem. I think.

Anyway, I hope that made some sense, and I'll try to revisit this tomorrow.

[This message has been edited by Jim Yingst (edited July 25, 2000).]

jayesh bindra
greenhorn
posted July 25, 2000 10:48 AM             
Hi,
I would like to thank maha anna and Jim for their detailed posts. It must have taken a lot of your time. Thank you very very much.

Jim,
Your observations seem to be correct. But I don't understand why it is so( I am referring to the fact that the inner interface MyInterface is being implemented by TestInterface3)
Thanks again.
Regards,
Jayesh.

P.S. I think the bugs like comets should be named after their discoverer. So this one should be called Jim or maha anna because of all the work you have put into this question.

vivek rai
ranch hand
posted July 25, 2000 11:48 AM             
JLS says - the member interfaces are always implicitly static so they are never considered to be inner classes.

i think for all purposes, we can treat interfaces defined inside a class to be equivalent to static inner classes. the following code illustrates the point, we dont get the errors for interfaces, but get them for inner class.

i have the earlier version of JDK, so can someone try this and see if this is giving the same error as the inner interface ( extending a static class defined inside)
--

code:

class B{};
class A extends B
{
static class B
{
static int i = 10;
};
class C
{
//static int i = 20; error Only members of interfaces and top-level classes can be static.
int i = 20;
};
interface D
{
int i = 30;
};
public static void main( String args[])
{
B b = new B();
System.out.println( B.i );
//System.out.println( C.i ); error
System.out.println( D.i );
}
}
}


---

Just have the feeling that bcoz its not exactly inner, and being a static member, is equivalent to a top level one, it might be confusing the compiler.

cheers,
vivek

[This message has been edited by maha anna (edited July 25, 2000).]

Jim Yingst
sheriff
posted July 25, 2000 01:01 PM             
I had forgotten that a nested interface is implicitly static, and thus I incorrectly called it "inner" in my previous post. I've since corrected it, along with a couple other errors. Thanks for the reminder, Vivek.

Using 1.3.0, your code does indeed give the same cyclic dependency error. But I don't think it's because of the implicit static nature of an interface. We get the same behavior using a (true) inner class instead of a nested interface:

code:

class MyClass { }

class Test extends MyClass {
class MyClass { }
}


Again, "cyclic inheritance involving Test". I think it's interpreting this as:
code:
class MyClass { }

class Test extends Test.MyClass {
class MyClass { }
}


(which gives the same error). If I change this to:
code:
package mypackage;

class MyClass { }

class Test extends mypackage.MyClass {
class MyClass { }
}


then the error goes away. So the problem is that when the compiler sees "class Test extends MyClass" it assumes that "MyClass" refers to the nested (inner in this case) MyClass (which isn't even in scope, technically IMO) rather than the package-level MyClass (which would be OK).

According to my reading of the JLS2 rules I linked to above, my second example above (in this post) should give an error (which it does) since Test depends directly on Test.MyClass, which depends directly on Test. But I don't see how the JLS2 rules apply to my first example (in this post), and I think it's a bug in the 1.3.0 compiler.

[This message has been edited by Jim Yingst (edited July 25, 2000).]

maha anna
bartender
posted July 25, 2000 01:49 PM             
Hello all,
What shall we do. Jim what do you think?. Shall we conclude this as a bug and register as a NEW BUG in Sun's site. We will register on behalf of Javaranch members.
regds
maha anna

Jim Yingst
sheriff
posted July 26, 2000 12:57 PM             
Yeah, I think it should be submitted as a bug. I'll do it this weekend unless you or someone else wants to do it before that.

|