在我深入研究泛型之前......你为什么不直接引入 aCheckableView
并返回该类型?
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 ...;
}
这个方法应该返回什么?如果您返回 a CheckableView
,编译器会说您必须将其强制转换为T
,因为客户端可能会将其强制转换为任何类型T
。但这也意味着您将收到一个从 CheckableView 到 T 的 Unchecked cast警告,因为如果客户端将其转换为除 之外的任何其他类型CheckableView
,例如OhterView
,您将收到一个ClassCastException
.
由于get
方法实现者无法知道客户端会将其转换为哪种类型,因此他无法确定返回哪个对象。
如果实现者返回一个特定的对象(例如CheckableView
),那么客户端只能将其转换为该类型。那么为什么实现者不更改方法签名以准确返回该类型呢?.... 或者为这种情况引入一个特殊的类型或接口?
也许这是您的解决方案
创建该get
方法将返回的接口,例如
public interface CheckableView {
}
更改 get 方法以返回一个CheckableView
private CheckableView get() {
}
编写一个适配器,使您View
实现的 sCheckable
适应CheckableView
public class CheckableViewAdapter<T extends View & Checkable> implements CheckableView {
private T checkableView;
public CheckableViewAdapter(T checkableView) {
this.checkableView = checkableView;
}
}
CheckableView
现在您可以为每个View
实现的 a 创建实例Checkable
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();
}