【发布时间】:2016-01-13 23:47:52
【问题描述】:
我有一个使用类型R 参数化的基本接口,扩展了相同的基本接口:
public interface IWidget<R extends IWidget<R>> {}
然后以同样的方式参数化另一个接口:
public interface IWidgetManager<R extends IWidget<R>> {}
最后,一个类实现了第二个接口。此类将在声明时收到IWidget implementation 类:
public class MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R> {}
我的问题:
我们可以使用什么更具体的类型来指定MyWidgetManager?
Class<?> 当然可以:
public Class<?> ok() {
return MyWidgetManager.class;
}
但它非常通用,我想要更具体的东西......
那些尝试无法编译:
public Class<? extends IWidgetManager<?>> fails() {
return MyWidgetManager.class;
}
==> 类型不匹配:无法从 Class
public <R extends IWidget<?>> Class<? extends IWidgetManager<R>> fails() {
return MyWidgetManager.class;
}
==> 类型不匹配:无法从 Class
public <R extends IWidget<R>> Class<? extends IWidgetManager<R>> fails() {
return MyWidgetManager.class;
}
==> 类型不匹配:无法从 Class
public Class<? extends IWidgetManager<? extends IWidget<?>>> fails() {
return MyWidgetManager.class;
}
==> 类型不匹配:无法从 Class
有什么方法可以让Class<?> 的类型比MyWidgetManager.class 更具体?
更新: 我更改了接口的名称。最后一个类不是一个小部件本身,这在我最初的问题中并不清楚......抱歉造成混淆。
更新 2:
确实,使用具体类型时事情会更容易。
这确实是针对我目前的情况,但我想我会通过将MyWidgetManager<R extends IWidget<R>> implements IWidgetManager<R> 转换为没有实现任何东西的WidgetManagerBase 来解决我的“问题”。然后提供一个带有具体 Widget 类的默认实现。最后,get 方法可以很容易地被覆盖(顺便说一句,这是我从一开始的主要目标!)。所以:
public interface IWidget<R extends IWidget<?>> {}
public interface IWidgetManager<R extends IWidget<R>> {}
public class WidgetManagerBase {}
// Default implementation
public class WidgetA implements IWidget<WidgetA> {}
public class AWidgetManager extends WidgetManagerBase implements IWidgetManager<WidgetA> {}
// default get method
public Class<? extends IWidgetManager<?>> getWidgetManagerClass() {
return AWidgetManager.class;
}
// 然后可以用 : 覆盖默认的 get 方法:
public class WidgetB implements IWidget<WidgetB> {}
public class BWidgetManager extends WidgetManagerBase implements IWidgetManager<WidgetB> {}
@Override
public Class<? extends IWidgetManager<?>> getWidgetManagerClass() {
return BWidgetManager.class;
}
【问题讨论】:
-
为什么不
public interface IBaseWidget<R extends IBaseWidget<R>> {}? -
@EpicPandaForce 好点,完成!谢谢。
-
您是否需要比
Class<?>更具体的类型?除了以类型安全的方式获取Constructor<T>对象和枚举常量(在枚举类型的情况下)之外,使用更具体的Class<...>类型并不能做太多事情。它只会使您的界面复杂化。我建议坚持使用Class<?>,除非真的有必要。 -
@Nándor Előd Fekete 问题是这是一种可以被覆盖的方法。我希望尽可能具体地作为它的返回类型,以尽可能地帮助子类实现者。
-
在使用递归泛型类型定义之前,请确保您确实需要它。如果只要求类型参数是
IWidget的子类,那么使用IWidget<R extends IWidget<?>>(它仍然保持类型安全)可以省去很多类型匹配的麻烦。仅在确实必须使用类型递归时才使用它。