【问题标题】:Java interfaces and return typesJava 接口和返回类型
【发布时间】:2011-01-25 17:02:16
【问题描述】:

假设我有以下界面:

public interface A { public void b(); }

但是,我希望实现它的每个类对方法 b() 具有不同的返回类型。

例子:

public class C { 
  public C b() {} 
}

public class D { 
  public D b() {} 
}

我将如何定义我的界面以使这成为可能?

【问题讨论】:

    标签: java generics interface types return


    【解决方案1】:

    如果返回类型必须是实现接口的类的类型,那么你想要的就叫做F-bounded type

    public interface A<T extends A<T>>{ public T b(); }
    
    public class C implements A<C>{
      public C b() { ... }
    }
    
    public class D implements A<D>{
      public D b() { ... }
    }
    

    换句话说,A 声明了一个类型参数T,它将采用实现A 的每个具体类型的值。这通常用于声明类型良好的 clone()copy() 方法。另一个例子,java.lang.Enum 使用它来声明每个枚举的继承 compareTo(E) 方法仅适用于该特定类型的其他枚举。

    如果你经常使用这种模式,你会遇到需要thisT 类型的场景。乍一看,它似乎很明显是1,但实际上您需要声明一个abstract T getThis() 方法,实现者必须将其简单地实现为return this

    [1] 正如评论者所指出的,如果XY 配合得当,就有可能做出像X implements A&lt;Y&gt; 这样的鬼鬼祟祟的事情。 T getThis() 方法的存在更清楚地表明X 正在规避A 接口作者的意图。

    【讨论】:

    • 离题:像这样的语法是我尽我所能避免创建通用 API 的原因。
    • 很好的答案(也是泛型力量的一个很好的例子),但这并不妨碍程序员做 C 实现 A(见我的第二个答案)。
    • @Matt McHenry:你为什么要指定嵌套的泛型类型?
    • @Matt McHenry:有什么具体的原因,为什么你要做 A> 而不仅仅是 A
    • 最后对A 的引用是原始类型。除了遗留代码之外的任何事情都应该避免这种情况。
    【解决方案2】:

    泛型。

    public interface A<E>{
        public E b();
    }
    
    public class C implements A<C>{
        public C b(){
            return new C();
        }
    }
    
    public class D implements A<D>{
        public D b(){
            return new D();
        }
    }
    

    搜索泛型以获取更多详细信息,但(非常)基本上,正在发生的事情是 AE 的类型留给实现类(CD)。

    所以基本上 A 不知道(也不必知道)E 在任何给定的实现中可能是什么。

    【讨论】:

    • 我比标记为“the”的答案更喜欢那个,因为您不必依赖实现者实际上会在通用声明中包含他们的类名这一事实。我对那个竖起大拇指。
    【解决方案3】:

    从 Java supports covariant return types(从 Java 1.5 开始),你可以这样做:

    public interface A { public Object b(); }
    

    【讨论】:

    • 不太好。您希望您的界面尽可能少地为意外误用留出空间。这样的方法,程序员在实现A时很容易出错。
    • 该问题没有明确指定对覆盖类型的任何限制。当然,如果存在此类限制,则应在可行的情况下通过接口强制执行它们。
    猜你喜欢
    • 2017-05-01
    • 2019-02-10
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多