简体   繁体   English

为实现接口的类强制执行返回类型

[英]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中是不可能的,但您可能想知道在界面中强制使用它的用例是什么。

  • If you program against the interface (which you typically do, why else define the interface) the type wouldn't be known 如果您针对接口进行编程(您通常会这样做,为什么还要定义接口),则不知道该类型
  • If you program against a specific class, this thread already provided options on how you can implement that specific class to return a 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM