【问题标题】:Java: Reference "own type" in interface [duplicate]Java:在接口中引用“自己的类型”[重复]
【发布时间】:2016-06-03 17:19:00
【问题描述】:

我想在一个接口中指定一个实现方法必须返回一个它自己类型的类。比如克隆方法:

interface MyArray{
    MyArray clone();
}

interface MyVector extends MyArray{
    // ... 1d-array specific methods
    MyVector clone();
}

class MyDoubleVector implements MyVector{
    //...
    @Override
    public MyDoubleVector clone(){
        //...
        return new MyDoubleVector(Arrays.copyOf(data));
    }
}

现在我可以打电话了:

MyVector vec1 = new DoubleVector(...);
MyVector vec2 = vec1.clone();

我想强制 MyArray 的所有实现者拥有一个克隆方法,该方法返回与实现者相同的类型。如果有一些内置的“元类型”表示“与此类/接口相同的类型”,我可以节省很多行,例如:

interface MyArray{
    <ArrayOfSameType> clone();
}

并且不必重新定义扩展接口中的方法来调用vec1->vec2克隆操作,如上所示。

Java 是否有一些内置结构可以做到这一点,或者复制和粘贴大量样板代码只是 Java 程序员的悲惨命运?

【问题讨论】:

  • 欢迎来到self-bound type parameters的古怪世界!
  • 丑陋的代码是糟糕程序员的悲惨命运。
  • @biziclop 真是个古怪的世界,谢谢。

标签: java generics types clone


【解决方案1】:

你需要使用泛型来实现这个

interface MyArray<A extends MyArray<A>> {
    A clone();
}

interface MyVector<A extends MyVector<A>> extends MyArray<A> {

}

class MyDoubleVector implements MyVector<MyDoubleVector> {
    //...
    @Override
    public MyDoubleVector clone(){
        //...
        return new MyDoubleVector(Arrays.copyOf(data));
    }
}

为了澄清一点,您需要extends MyArray&lt;A&gt; 以防止开发人员编写以下内容。

MyArray<Integer> mi = new SomeMyArray<>();
Integer i = mi.clone();

这会编译得很好,但显然应该在运行时失败。

【讨论】:

  • 等等,我刚试了下还是不行(它仍然认为克隆一个MyVector的输出应该是一个MyArray)。但是,如果我用以下方式声明 MyVector,它就可以正常工作:interface MyVector extends MyArray&lt;MyVector&gt;
  • 绑定是不必要的——如果声明为interface MyArray&lt;A&gt;
  • @newacct 它会编译,除非你可以执行 Integer i = myArray.clone(); 并得到运行时错误。
  • @PeterLawrey:不,这没有任何意义。它不会出现运行时错误,就像您的代码会出现运行时错误一样。如果myArray 是实现MyArray&lt;Integer&gt; 并且安全实现的类型,那么它应该返回Integer;为什么这会导致任何运行时错误?如果myArray 是实现MyArray&lt;SomethingElse&gt; 的类型,那么它将无法编译。
  • @newacct 请再次阅读我的评论,我没有在任何地方提及MyArray&lt;Integer&gt;
【解决方案2】:

我认为您需要的是 F-Bound 类型。您可以查看this 线程以获取类似示例。

【讨论】:

    猜你喜欢
    • 2020-11-12
    • 2019-01-13
    • 1970-01-01
    • 2019-12-12
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    相关资源
    最近更新 更多