当接口A在其方法签名中定义接口B.

时间:2016-02-18 19:28:19

标签: java inheritance

...如何限制A的实现以在方法签名中使用B的某个实现?

使用案例

这是一个Unit接口和两个实现它的枚举:

public interface Unit { ... }

public enum ForceUnit implements Unit { ... }
public enum MassUnit implements Unit { ... }

Property界面使用的是:

public interface Property {

    public void setUnit( Unit unit );    // for example
}

public class Force implements Property { ... }
public class Mass implements Property { ... }

在这里,我希望能够强制执行:

  • Force仅在ForceUnit签名
  • 中使用setUnit
  • Mass仅在MassUnit签名
  • 中使用setUnit

当我尝试这样做时,Eclipse抱怨道:

  

类型Mass必须实现继承的抽象方法Property.setUnit(unit)

并及时提出两个快速解决方法:

  • 使类抽象,这不是一个选项,因为我希望能够做Mass mass = new Mass();
  • 这样的事情
  • 使用@Override注释添加未实现的方法。我不知道这是不是正确的解决办法,但对我来说这有点笨拙。

问题

  • 我有什么选择来实现我想要的?使用仿制药会不会有帮助?
  • 为什么将类标记为抽象解决问题?

1 个答案:

答案 0 :(得分:12)

您可以使用泛型

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.
  

为什么将类标记为抽象可以解决问题?

使类抽象意味着setUnit(Unit)实际上并未实现,但对于抽象类,这是可以的。