Phi*_*hke 44 java generics interface
有没有一种方法在java中指定,泛型类的类型参数必须是一个接口(而不仅仅是扩展它!)
我想做的是以下内容:
public class MyClass<X extends SomeInterface, Y extends SomeOtherClass & X>
Run Code Online (Sandbox Code Playgroud)
这意味着Y必须是SomeOtherClass的子类并实现X.编译器目前得到的是
X型不是界面; 它不能指定为有界参数
那么,我怎样才能告诉编译器X必须始终是一个接口?
编辑:
好的,我想我稍微简化了我的问题.让我们使用我的实际应用程序域来使其更清晰:
我有一个用于表示图表的API.一图包含节点和边缘对象.所有这三个类都实现了Shape接口.形状可以具有子形状,父形状并且属于图形.
问题是,我需要制作这个API的两个版本:一个只具有基本功能的开源和一个具有更多功能的扩展版本.但是,扩展API必须只提供返回扩展类型的方法(ExtendedDiagram,ExtendedNode,ExtendedEdge和(此处出现问题)ExtendedShape).
所以我有这样的事情:
/* BASIC CLASSES */
public interface Shape<X extends Shape<X,Y>, Y extends Diagram<X,Y>>{
public List<X> getChildShapes();
public X getParent();
public Y getDiagram();
...
}
public class Diagram<X extends Shape<X,Y>, Y extends Diagram<X,Y>> implements Shape<X,Y>{...}
public class Edge<X extends Shape<X,Y>, Y extends Diagram<X,Y>> implements Shape<X,Y>{...}
...
/* EXTENDED CLASSES */
public interface ExtendedShape extends Shape<ExtendedShape,ExtendedDiagram> { ... }
public class ExtendedDiagram extends Diagram<ExtendedShape,ExtenedDiagram> implements ExtendedShape { ... }
public class ExtendedEdge extends Edge<ExtendedShape,ExtenedDiagram> implements ExtendedShape { ... }
...
Run Code Online (Sandbox Code Playgroud)
扩展API工作正常,基本API代码提供了一些警告,但使用基本API时会出现主要问题:
public class SomeImporter<X extends Shape<X,Y>, Y extends Diagram<X,Y>, E extends Edge<X,Y>>{
private Y diagram;
public void addNewEdge(E newEdge){
diagram.addChildShape(newEdge);
...
Run Code Online (Sandbox Code Playgroud)
最后一行给了我以下警告:
方法中的方法addChildShape(X)不适用于参数(E)
所以现在,我只想指出E还需要实现X,一切都会好的 - 我希望;)
这一切都有意义吗?你们知道这样做的方法吗?或者是否有更好的方法来获得具有上述限制的扩展API?
感谢您坚持我,非常感谢任何帮助!
idi*_*kop 15
您可以使用:
class Foo<T extends Number & Comparable> {...}
Run Code Online (Sandbox Code Playgroud)
具有一个类型参数的类Foo,必须使用类型为Number并且实现Comparable的类型实例化T.Foo.
在泛型上下文中,<Type extends IInterface>处理扩展和实现。这是一个例子:
public class GenericsTest<S extends Runnable> {
public static void main(String[] args) {
GenericsTest<GT> t = new GenericsTest<GT>();
GenericsTest<GT2> t2 = new GenericsTest<GT>();
}
}
class GT implements Runnable{
public void run() {
}
}
class GT2 {
}
Run Code Online (Sandbox Code Playgroud)
GenericsTest 将接受 GT,因为它实现了 Runnable。GT2 没有,因此在尝试编译第二个 GenericsTest 实例时会失败。
也许你可以稍微简化你的模型:太多的泛型很快就会在可读性方面变得非常痛苦,如果你定义一个公共 API,这将是一个很大的问题。通常,如果您无法再理解括号内应该包含的内容,那么您就超出了您的需求 - 并且您不能指望用户比您自己更好地理解它......
无论如何,为了使您的代码编译,您可以尝试在Shape类型中定义类似的内容:
public <S extends Shape<?,?>> void addChildShape(S shape);
Run Code Online (Sandbox Code Playgroud)
应该可以做到这一点。
华泰