[英]Enforcing return type for an class that implements an interface
How do I enforce that the method getFoo() in the implementing class, returns a list of the type of same implementing class. 如何在实现类中强制执行getFoo()方法,返回相同实现类的类型列表。
public interface Bar{
....
List<? extends Bar> getFoo();
}
Right now a class that implements Bar returns objects of any class that implements Bar. 现在,实现Bar的类返回实现Bar的任何类的对象。 I want to make it stricter so that the class that implements Bar returns a List of objects of only its type in getFoo().
我想让它更严格,以便实现Bar的类在getFoo()中返回一个只有它类型的对象的List。
Unfortunately this cannot be enforced by Java's type system. 不幸的是,这不能由Java的类型系统强制执行。
You can get pretty close, though, by using: 不过,你可以通过以下方式使用:
public interface Bar<T extends Bar<T>> {
List<T> getFoo();
}
And then your implementing classes can implement it like so: 然后你的实现类可以像这样实现它:
public class SomeSpecificBar implements Bar<SomeSpecificBar> {
// Compiler will enforce the type here
@Override
public List<SomeSpecificBar> getFoo() {
// ...
}
}
But nothing stops another class from doing this: 但没有什么可以阻止另一个类这样做:
public class EvilBar implements Bar<SomeSpecificBar> {
// The compiler's perfectly OK with this
@Override
public List<SomeSpecificBar> getFoo() {
// ...
}
}
This is not possible in Java, but you might wonder what the use-case is to force this in the interface. 这在Java中是不可能的,但您可能想知道在界面中强制使用它的用例是什么。
List<itself>
. List<itself>
。 And since you program against that specific class, the compiler has access to that specific return type and knows about it The interface Bar<T extends Bar<T>>
answers already here are right, but I just wanted to add that if this is really something you want to enforce, you may want to look at composing your objects rather than using inheritance. 这里的
interface Bar<T extends Bar<T>>
答案是正确的,但我只是想补充一点,如果这是你想要强制执行的东西,你可能想要看看编写你的对象而不是使用继承。 Without knowing too much about your classes, it might look something like this: 如果不太了解你的课程,它可能看起来像这样:
public interface FooGetter<T> {
List<? extends T> getFoo();
}
public class FooComposer<T extends Bar> {
...
final T bar;
final FooGetter<T> barGetter;
}
Or it could look very different... but the main point is that if you want the two Ts to match, composition may be the answer. 或者它可能看起来非常不同......但重点是如果你想让两个Ts匹配,那么组合可能就是答案。
Of course, even that can be circumvented using raw types... but then again, if someone does that, they're just using a raw List
, and when they get ClassCastExceptions you can safely hit them. 当然,即使这样也可以使用原始类型来规避...但是,如果有人这样做,他们只是使用原始
List
,当他们获得ClassCastExceptions时,你可以安全地击中它们。 :) :)
You should infer the generic on Bar
: 你应该在
Bar
上推断泛型:
public interface Bar<T extends Foo> {
...
List<T> getFoo();
}
You can just parameterize the method, but that will not ensure that the return type matches that of the class. 您可以只参数化方法,但这不能确保返回类型与类的匹配。
Maybe sth like this 也许是这样的
public interface Bar {
....
List<? extends Bar> getFoo();
}
public class T implements Bar {
List<T> getFoo();
}
public class TestClass extends T {};
I liked yshavit answer best but I could not understand the code. 我最喜欢yshavit的答案,但我无法理解代码。 So I will try to write the code as I think it should be.
所以我会尝试编写我认为应该的代码。
interface Bar
{
// stuff
// don't bother with the getFoo method
}
interface BarUtils
{
< T extends Bar > List < ? extends T > getFoo ( T bar ) ;
}
How about this: 这个怎么样:
interface Bar
{
// everything but getFoo ( ) ;
}
interface FooGetter < T >
{
List < ? extends T > getFoo ( ) ;
}
interface BarRef < T extends Bar & FooGetter < T > >
{
T get ( ) ;
}
anything that implements BarRef must implement T and anything that implements T must have the appropriately enforced getFoo method. 任何实现BarRef的东西都必须实现T,任何实现T的东西都必须有适当强制的getFoo方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.