[英]How can I make an interface instance method accept arguments of the same class only?
I want to use an interface like this : 我想使用这样的界面:
public interface ResultItem {
public int getConfidence();
public boolean equals(ResultItem item);
public ResultItem cloneWithConfidence(int newConfidence);
}
I have it implemented by different kind of objects representing a voice recognition result. 我通过表示语音识别结果的不同类型的对象来实现它。
The idea is, I wish to compare only results of the same kind. 我的想法是,我希望只比较同类的结果。 That is, if I create a class IntResult
implementing ResultItem
, I want that the method signatures become : 也就是说,如果我创建了一个类IntResult
实现ResultItem
,我想,该方法的签名变成了:
public boolean equals(IntResult item);
public IntResult cloneWithConfidence(int newConfidence);
I feel that there is a design flaw in my interface, because for now I am using pretty ugly casts on the results of cloneWithConfidence and of other methods returning a ResultItem. 我觉得我的界面中存在设计缺陷,因为现在我在cloneWithConfidence和返回ResultItem的其他方法的结果上使用非常难看的强制转换。
Is there a better way? 有没有更好的办法?
There is a frequently-seen idiom that goes as follows: 有一种常见的习语如下:
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> {
//...
}
Not really an answer to your question, but an important remark (I think): 不是你的问题的答案,而是一个重要的评论(我认为):
If you want your equals-method to be usable for objects in collections and similar, you need to implement public boolean equals(Object o)
, and it should work for comparisons to all kinds of objects (in most cases returning false, though). 如果你希望你的equals方法可用于集合中的对象和类似的东西,你需要实现public boolean equals(Object o)
,它应该适用于比较所有类型的对象(在大多数情况下,返回false)。 You may have additionally a method with a narrower parameter type, and in implementations delegate like this: 您可能还有一个具有较窄参数类型的方法,并且在实现中委托如下:
public class IntResult {
public boolean equals(Object o) {
return o instanceof IntResult &&
this.equals((IntResult)o);
}
public boolean equals(IntResult that) {
// TODO
}
}
Make sure you comply to all the conditions in the contract of equals, namely symmetry, reflexivity, transitivity and having a compatible hashCode implementation. 确保遵守equals合同中的所有条件,即对称性,反身性,传递性和兼容的hashCode实现。
Well, you could make it generic: 好吧,你可以把它变成通用的:
public interface ResultItem<T extends ResultItem<T>> {
public boolean equals(ResultItem<T> item);
}
Then you would need to make IntResult
implement ResultItem<IntResult>
. 然后,您需要使IntResult
实现ResultItem<IntResult>
。
Of course that doesn't stop another class from misbehaving, eg FloatResult
implementing ResultItem<IntResult>
but it makes various bits of API work when all the classes are well behaved. 当然,这并不能阻止另一个类行为不端,例如FloatResult
实现ResultItem<IntResult>
但是当所有类都表现良好时,它会使各种API工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.