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

Zai*_*aid 10 java inheritance

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

用例

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

public interface Unit { ... }

public enum ForceUnit implements Unit { ... }
public enum MassUnit implements Unit { ... }
Run Code Online (Sandbox Code Playgroud)

Property接口使用哪个:

public interface Property {

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

public class Force implements Property { ... }
public class Mass implements Property { ... }
Run Code Online (Sandbox Code Playgroud)

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

  • ForceForceUnitsetUnit签名中使用
  • MassMassUnitsetUnit签名中使用

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

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

并及时建议两个快速修复:

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

问题

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

Pet*_*rey 13

你可以使用泛型

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) { }
}
Run Code Online (Sandbox Code Playgroud)

注意:这确实意味着你仍然可以

Property raw = new Mass();
raw.setUnit(ForceUnit.NEWTON); // ClassCastException
Run Code Online (Sandbox Code Playgroud)

但是这会导致类强制转换异常,因为编译器无法在运行时检查原始类型.

你应该做的是

Property<Mass> raw = new Mass();
raw.setUnit(ForceUnit.NEWTON); // doesn't compile.
Run Code Online (Sandbox Code Playgroud)

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

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

  • 哇,那太快了!这应该绝对有效 (2认同)