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

时间:2021-04-20 20:33:40

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?

有更好的方法吗?

3 个解决方案

#1


10  

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> {
  //...
}

#2


4  

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). You may have additionally a method with a narrower parameter type, and in implementations delegate like this:

如果您希望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
    }

}

Make sure you comply to all the conditions in the contract of equals, namely symmetry, reflexivity, transitivity and having a compatible hashCode implementation.

确保您遵守了相等性契约中的所有条件,即对称、自反性、传递性和具有兼容的hashCode实现。

#3


1  

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)执行“无畏”(IntResult>)。

Of course that doesn't stop another class from misbehaving, e.g. FloatResult implementing ResultItem<IntResult> but it makes various bits of API work when all the classes are well behaved.

当然,这并不能阻止另一个类的不当行为,例如,FloatResult实现了ResultItem ,但是当所有的类都表现良好时,它会使各种各样的API工作。

#1


10  

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> {
  //...
}

#2


4  

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). You may have additionally a method with a narrower parameter type, and in implementations delegate like this:

如果您希望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
    }

}

Make sure you comply to all the conditions in the contract of equals, namely symmetry, reflexivity, transitivity and having a compatible hashCode implementation.

确保您遵守了相等性契约中的所有条件,即对称、自反性、传递性和具有兼容的hashCode实现。

#3


1  

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)执行“无畏”(IntResult>)。

Of course that doesn't stop another class from misbehaving, e.g. FloatResult implementing ResultItem<IntResult> but it makes various bits of API work when all the classes are well behaved.

当然,这并不能阻止另一个类的不当行为,例如,FloatResult实现了ResultItem ,但是当所有的类都表现良好时,它会使各种各样的API工作。