繁体   English   中英

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

[英]Enforcing return type for an class that implements an interface

如何在实现类中强制执行getFoo()方法,返回相同实现类的类型列表。

public interface Bar{
     ....
     List<? extends Bar> getFoo(); 
}

现在,实现Bar的类返回实现Bar的任何类的对象。 我想让它更严格,以便实现Bar的类在getFoo()中返回一个只有它类型的对象的List。

不幸的是,这不能由Java的类型系统强制执行。

不过,你可以通过以下方式使用:

public interface Bar<T extends Bar<T>> {
    List<T> getFoo();
}

然后你的实现类可以像这样实现它:

public class SomeSpecificBar implements Bar<SomeSpecificBar> {
    // Compiler will enforce the type here
    @Override
    public List<SomeSpecificBar> getFoo() {
        // ...
    }
}

但没有什么可以阻止另一个类这样做:

public class EvilBar implements Bar<SomeSpecificBar> {
    // The compiler's perfectly OK with this
    @Override
    public List<SomeSpecificBar> getFoo() {
        // ...
    }
}

这在Java中是不可能的,但您可能想知道在界面中强制使用它的用例是什么。

  • 如果您针对接口进行编程(您通常会这样做,为什么还要定义接口),则不知道该类型
  • 如果针对特定类进行编程,则此线程已经提供了有关如何实现该特定类以返回List<itself> 并且由于您针对该特定类进行编程,因此编译器可以访问该特定的返回类型并了解它

这里的interface Bar<T extends Bar<T>>答案是正确的,但我只是想补充一点,如果这是你想要强制执行的东西,你可能想要看看编写你的对象而不是使用继承。 如果不太了解你的课程,它可能看起来像这样:

public interface FooGetter<T> {
    List<? extends T> getFoo();
}

public class FooComposer<T extends Bar> {
    ...
    final T bar;
    final FooGetter<T> barGetter;
}

或者它可能看起来非常不同......但重点是如果你想让两个Ts匹配,那么组合可能就是答案。

当然,即使这样也可以使用原始类型来规避...但是,如果有人这样做,他们只是使用原始List ,当他们获得ClassCastExceptions时,你可以安全地击中它们。 :)

你应该在Bar上推断泛型:

public interface Bar<T extends Foo> {
  ...
  List<T> getFoo();
}

您可以只参数化方法,但这不能确保返回类型与类的匹配。

也许是这样的

public interface Bar {
     ....
     List<? extends Bar> getFoo(); 
}

public class T implements Bar {
     List<T> getFoo();
}

public class TestClass extends T {};

我最喜欢yshavit的答案,但我无法理解代码。 所以我会尝试编写我认为应该的代码。

interface Bar
{
    // stuff
    // don't bother with the getFoo method
}

interface BarUtils
{
    < T extends Bar > List < ? extends T > getFoo ( T bar ) ;
}

这个怎么样:

interface Bar
{
    // everything but getFoo ( ) ;
}

interface FooGetter < T >
{
    List < ? extends T > getFoo ( ) ;
}

interface BarRef < T extends Bar & FooGetter < T > >
{
    T get ( ) ;
}

任何实现BarRef的东西都必须实现T,任何实现T的东西都必须有适当强制的getFoo方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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