在我深入研究泛型之前......
为什么不直接引入 CheckableView 并返回该类型?
public class CheckableView extends View implements Checkable {
}
private CheckableView getCheckableView() {
return checkableView;
}
如果View 是一个接口,它可以工作:
interface View {}
interface Checkable {}
class CheckableView implements Checkable, View {}
public class Main {
private static CheckableView checkableView;
private static <T extends View & Checkable> T get() {
return (T) checkableView;
}
public static void main(String[] args) {
View view = Main.get();
Checkable checkable = Main.get();
}
}
我认为理解泛型的问题在于T extends View & Checkable在实际情况下并不意味着你可以返回任何扩展View并实现Checkable的类型。
这意味着客户端可以将返回的类型强制转换为任何扩展View并实现Checkable的类型。
客户可以这样做:
class CheckableView extends View implements Checkable {}
class OtherView extends View implements Checkable {}
private static <T extends View & Checkable> T get() {
return (T) checkableView;
}
OtherView otherView = Main.get();
CheckableView checkableView = Main.get();
但是您现在想对实现做什么?
private <T extends View & Checkable> T get() {
return ...;
}
这个方法应该返回什么?如果您返回CheckableView,编译器会说您必须将其转换为T,因为客户端可能会将其转换为任何类型T。但这也意味着您将收到 Unchecked cast from CheckableView to T 警告,因为如果客户端将其转换为 CheckableView 以外的任何其他类型,例如OhterView,你会得到一个ClassCastException。
由于get 方法的实现者无法知道客户端会将其转换为哪种类型,因此他无法确定要返回哪个对象。
如果实现者返回一个特定的对象(例如CheckableView),那么客户端只能将其转换为该类型。那么为什么实现者不更改方法签名以准确返回该类型呢? .... 或者为这种情况引入一个特殊的类型或接口?
也许这是适合您的解决方案
创建get方法将返回的接口,例如
public interface CheckableView {
}
更改 get 方法以返回 CheckableView
private CheckableView get() {
}
编写一个适配器,使实现Checkable 的Views 适应CheckableView
public class CheckableViewAdapter<T extends View & Checkable> implements CheckableView {
private T checkableView;
public CheckableViewAdapter(T checkableView) {
this.checkableView = checkableView;
}
}
现在您可以为每个实现Checkable 的View 创建CheckableView 的实例
class SomeView extends View implements Checkable {}
SomeView someView = ...;
CheckableView checkableView = new CheckableViewAdapter<SomeView>(someView);
将get方法的客户端需要的方法添加到CheckableView接口中,并在CheckableViewAdapter中实现。
public interface CheckableView {
public void bringToFront();
}
public class CheckableViewAdapter<T extends View & Checkable> implements CheckableView {
private T checkableView;
public CheckableViewAdapter(T checkableView) {
this.checkableView = checkableView;
}
public void bringToFront(){
checkableView.bringToFront();
}
}
或者只是
public interface CheckableView {
public View getView();
public Checkable getCheckable();
}