如何使接口实例方法仅接受同一类的参数?

时间:2011-03-01 16:22:42

标签: java interface methods

我想使用这样的界面:

public interface ResultItem {
    public int getConfidence();
    public boolean equals(ResultItem item);
    public ResultItem cloneWithConfidence(int newConfidence);
}

我通过表示语音识别结果的不同类型的对象来实现它。

我的想法是,我希望只比较同类的结果。也就是说,如果我创建一个实现IntResult的类ResultItem,我希望方法签名变为:

public boolean equals(IntResult item);
public IntResult cloneWithConfidence(int newConfidence);

我觉得我的界面存在设计缺陷,因为现在我对cloneWithConfidence和返回ResultItem的其他方法的结果使用非常难看的强制转换。

有更好的方法吗?

3 个答案:

答案 0 :(得分:11)

有一种常见的习语如下:

public interface ResultItem<T extends ResultItem<T>> {
    public int getConfidence();
    public boolean equals(T item);
    public T cloneWithConfidence(int newConfidence);
}

public class IntResult implements ResultItem<IntResult> {
  //...
}

答案 1 :(得分:4)

不是你问题的答案,而是一个重要的评论(我认为):

如果您希望equals-method可用于集合中的对象和类似对象,则需要实现public boolean equals(Object o),它应该可以用于比较各种对象(在大多数情况下,返回false) 。您可能还有一个具有较窄参数类型的方法,并且在实现中委托如下:

public class IntResult {
    public boolean equals(Object o) {
        return o instanceof IntResult &&
             this.equals((IntResult)o);
    }
    public boolean equals(IntResult that) {
        // TODO
    }

}

确保遵守equals合同中的所有条件,即对称性,反身性,传递性以及兼容的hashCode实现。

答案 2 :(得分:1)

嗯,你可以把它变成通用的:

public interface ResultItem<T extends ResultItem<T>> {
    public boolean equals(ResultItem<T> item);
}

然后您需要IntResult实施ResultItem<IntResult>

当然,这并不能阻止另一类人行为不端,例如: FloatResult实施ResultItem<IntResult>,但当所有类 表现良好时,它会使各种API工作。