![](/img/trans.png)
[英]Java Generics - Best way to use generic interface and its implementation
[英]How would I use generics in Java to create a generic interface that defines a method that only accepts the implementation as a parameter?
有没有一种方法可以在接口中定义一个方法,在其中可以将实现键入到实现类中? 这是我最初尝试解决该问题的具体示例,但我会指出失败的地方。
public interface ErrorMeasurable<T extends ErrorMeasurable<T>> {
// I want every implementation of this method to accept
// the implementing type as a parameter. I'm willing to accept
// that programmers can maliciously type it to something else
// that meets the type boundary. I'm not willing to accept
// polymorphic usage to be verbose or strange as the below example shows.
boolean approxEquals(T that);
}
// This works...
public class MyDecimal implements ErrorMeasurable<MyDecimal> {
boolean approxEquals(MyDecimal that) { ... }
}
// But polymorphism doesn't work well...
public interface MyNumber<T extends ErrorMeasurable<T>> implements ErrorMeasurable<T> {
boolean approxEquals(T that) { ... }
}
public class MyDecimal2 implements MyNumber<MyDecimal> {
boolean approxEquals(MyDecimal that) { ... }
}
public class UsesNumbers {
// PROBLEM 1: the type parameter is unbound.
MyNumber rawNumber1, rawNumber2;
// PROBLEM 2: This binds the type parameter but it is hard to understand why its typed to itself
MyNumber<MyNumber> boundNumber1, boundNumber2;
void example() {
// PROBLEM 3: There will be a compiler warning about the raw types.
rawNumber1.approxEquals(rawNumber2);
// Works without warnings, see PROBLEM 2 though.
boundNumber1.approxEquals(boundNumber2);
}
}
我认为用Java当前的泛型级别无法完成您想要的事情。
您不能采取任何行动来阻止将泛型用作原始类型的其他人,但这至少会发出警告。 如果没有警告,则保证代码是类型安全的。
对于问题2,您可能想要的是:
public interface MyNumber<T extends MyNumber<T>> implements ErrorMeasurable<T> {
boolean approxEquals(T that) { ... }
}
public class MyDecimal2 implements MyNumber<MyDecimal2> {
boolean approxEquals(MyDecimal2 that) { ... }
}
public class MyDecimal3 extends MyDecimal2 {
boolean approxEquals(MyDecimal2 that) { ... }
}
public class UsesNumbersClass<T extends MyNumber<T>> {
T boundNumber1, boundNumber2;
void example() {
boundNumber1.approxEquals(boundNumber2);
}
}
public class UsesNumbersOnlyMethod {
<T extends MyNumber<T>> void example(T boundNumber1, T boundNumber2) {
boundNumber1.approxEquals(boundNumber2);
}
}
每个类只能具有方法boolean approxEquals(T that)
单个实际实现,因此,您必须为每个类确定是否要使用该方法精确地表示该类(例如MyDecimal2
),或者希望它能够处理更大的范围。类型-一些父类型(例如MyDecimal3
)。 几乎总是希望它完全处理该类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.