…如何限制A的实现在方法签名中使用B的某个实现?
用例
这是一个Unit接口和两个实现它的枚举:
public interface Unit { ... } public enum ForceUnit implements Unit { ... } public enum MassUnit implements Unit { ... }
属性界面使用哪个:
public interface Property { public void setUnit( Unit unit ); // for example } public class Force implements Property { ... } public class Mass implements Property { ... }
在这里我想要能够执行:
> Force在setUnit签名中只使用ForceUnit
> Mass在setUnit签名中只使用MassUnit
当我尝试这样做,Eclipse抱怨:
The type
Mass
must implement the inherited abstract methodProperty.setUnit(unit)
并及时提出两个快速修复:
>使类抽象,这不是一个选项,因为我想要能够像Mass mass = new Mass();
>使用@Override注释添加未实现的方法.我不知道这是否是正确的解决方案,但对我来说这个笨拙的笑容.
问题
解决方法
你可以使用泛型
public interface Property<U extends Unit> { public void setUnit(U unit ); // for example } public class Force implements Property<ForceUnit> { @Override public void setUnit(ForceUnit unit) { } } public class Mass implements Property<MassUnit> { @Override public void setUnit(MassUnit unit) { } }
注意:这的确意味着你仍然可以做
Property raw = new Mass(); raw.setUnit(ForceUnit.NEWTON); // ClassCastException
然而,这将导致类转换异常,因为编译器无法在运行时检查原始类型.
你应该做的是
Property<Mass> raw = new Mass(); raw.setUnit(ForceUnit.NEWTON); // doesn't compile.
Why does marking the class as abstract resolve the issue?
使类抽象意味着setUnit(Unit)实际上并没有被实现,但是对于抽象类,这是可以的.