Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics: why can't inner interface implement from a (inner) superinterface?

I have an interface like this:

public interface SuperInterface {
    public interface SubInterface {
        public void get();
    }
    //**More interfaces*/

}

this method in my Toolkit, which retrieves all objects which are instance of a certain class:

public static <T> ArrayList<T> getSome(ArrayList<Object> objects, Class<T> clazz) {
    ArrayList<T> result = new ArrayList<T>();
    for (Object o : objects) 
        if (clazz.isInstance(o)) 
            result.add(clazz.cast(o));
    return result;
}

MyClass is not really interesting, its an empty class implementing from SuperInterface.SubInterface

And this piece in the main:

ArrayList<Object> mObjects = new ArrayList<Object>() {
    {
        add(new MyClass()); //SuperInterface.SubInterface
        add(Integer.valueOf(5));
        add(new String("Hello"));
        add(new Object());
    }
};
ArrayList<SuperInterface> mSuperInterfaces = Toolkit.getSome(mObjects, SuperInterface.class); //returns a zero-sized list.
ArrayList<SuperInterface.SubInterface> mSubInterfaces = Toolkit.getSome(mObjects, SuperInterface.SubInterface.class); //returns a one-sized list

The first method call does not work as I hoped, the second does. Is it possible so that the first one works without explicitly putting the subinterfaces in a different file and implementing the superclass? Because apparently the subinterfaces aren't really subinterfaces, so I tried to make the Interface class like this:

public class ClassWithInterfaces {
  public interface Super { }
  public interface Sub implements Super { /**...*/ }
}

But apparently you can't use implements in an inner interface.

My question is: Why is that, and is there a way to accomplish what I want to achieve (inner interfaces in one file)? I don't necessarily need it, I merely want to know why it's not possible to implement in inner interfaces (yet it's possible to extend inner classes).

like image 767
stealthjong Avatar asked Dec 11 '12 10:12

stealthjong


2 Answers

But apparently you can't use implements in an inner interface.

You're looking for extends rather than implements:

public class ClassWithInterfaces {
  public interface Super { }
  public interface Sub extends Super { /**...*/ }
}

This compiles for me, and I can certainly implement both interfaces.

Since there appears to be some confusion around extending vs implementing, perhaps the following will help clear things up:

  • An interface extends another interface.
  • A class implements an interface.
  • A class extends another class.
like image 155
NPE Avatar answered Nov 15 '22 02:11

NPE


According to the Java Language Specification:

So here you have two reasons why you can't have "real" inner interfaces

Also, as NPE writes, an interface can never implement another interface, it can only extend it. Classes can implement interfaces and / or extend classes, interfaces can only extend interfaces. Makes perfect sense to me.

like image 31
Sean Patrick Floyd Avatar answered Nov 15 '22 02:11

Sean Patrick Floyd