views:

122

answers:

3

Consider the following two Java files that contain a simplified version of my issue

#a.java
package a;
public interface I {
 //...
}

#b.java
package b;
public interface I {
 //... (different stuff from a.I)
}

You'll notice within my project there are two interfaces named "I". This cannot be changed. I am in a situation where I need to use both types inside a single class. Now of course, I could just reference each of their types as a.I and b.I, but I'm trying to avoid it for nothing other than maintaining readability.

I want to do something like this

interface B extends b.I {

}

This could let me use the interface of I by using B and, and a.I as just I by importing. The problem is that this doesn't work, let's take this concrete example using

interface MyList extends List<String> {
}

MyList l = new ArrayList<String>();

This yields a type error. Why doesn't Java "know" that MyList extends List?

Also, I've tried casting in the above example, but it generates a ClassCastException

Thoughts?

+1  A: 

Java does know that MyList extends List<String>, but it also knows perfectly well that ArrayList<String> does NOT implement MyList. I would strongly recommend removing ambiguities in the simplest, clearest, cleanest, most readable way: use a.I and b.I!

Alex Martelli
+6  A: 

This is valid:

List<String> list = new MyList();

This is not:

MyList l = new ArrayList<String>();

ArrayList is not a MyList. They just have a common superinterface. That's why it doesn't work. Java "knows" MyList is a List but that doesn't mean you can assign a List to it.

Consider:

public interface MyList extends List<String> {
  void foo();
}

MyList l = new ArrayList<String>();
l.foo();

Obviously ArrayList does not have the foo() method.

cletus
+1  A: 

You can't cast an ArrayList<String> into a MyList because MyList is not a super-class or super-interface of ArrayList<String>. Pretend you actually added a method to MyList, say MyList.swizzle(). What would happen if Java allowed the cast and then you called l.swizzle()?

I don't think you're going to find a satisfactory solution to this since Java does not have an import as type renaming statement. But implementing an interface to add its members to your class's namespace is contraindicated in Java 1.5: if you're going to go down that route, give static import a try instead. It is the preferred idiom nowadays for doing what you're trying to do.

John Kugelman