如何从实现的类中确定方法的返回类型?

时间:2014-03-19 13:38:52

标签: java

我有一组用于存储数据的类,我目前正在尝试实现深层复制机制。为此,我想在我的抽象类中定义一个方法deepCopy(),每个扩展类都需要实现它。

我正在努力以通用的方式定义抽象方法,以便每个deepCopy()返回它所实现的类的Object。

public abstract class Foo {
    public abstract Foo deepCopy();
}

public class Bar extends Data {
    @Override
    public Bar deepCopy() {
        //copying;
    }
}

这是我想要实现的目标,但我最终得到了这个:

public abstract class Foo {
    public abstract Foo deepCopy();
}

public class Bar extends Data {
    @Override
    public Foo deepCopy() {
        //copying;
    }
}

调用deepCopy()时会出错:

public SomeClass extends Foo {
    private Bar value;

    private SomeClass(final SomeClass original) {
        this.value = original.deepCopy(); // type-mismatch since deepCopy returns Foo but value is Bar.
    }

    @Override
    public Foo deepCopy() {
        return new SomeClass(this);
    }
}

解决此问题的最简单方法是将deepCopy的返回对象强制转换为Bar,但这似乎不对。

有没有一种干净的方法来实现这一目标?

2 个答案:

答案 0 :(得分:0)

您可以使用java中的Generics执行此操作。

像这样实现这个类。

public abstract class Foo<Item> {
    public abstract Item deepCopy();
}

您可以在此处阅读有关泛型的信息http://docs.oracle.com/javase/tutorial/java/generics/

答案 1 :(得分:0)

协变返回类型似乎可以解决这个问题:

public abstract class Foo {
    public abstract Foo deepCopy();
}

然后Bar可以从方法中返回Bar

public class Bar extends Foo {
    @Override
    public Bar deepCopy() {
        //copying;
    }
}

所以:

final Bar bar = new Bar();
final Bar barCopy = bar.deepCopy(); // <- Bar's deepcopy returns a Bar
final Foo foo = ((Foo) bar).deepCopy(); // <- Foo's deepcopy returns a Foo

这是允许的,因为Bar extends Foo Bar可以使用Foo,只要您可以使用public abstract class Foo { public abstract Number getThing(); } public class Bar extends Foo { @Override public Integer getThing() { //copying; } } 。因此,子类可以覆盖返回协变类型的超类中的方法。

这适用于更一般的情况:

Bar.getThing

如您所见,Integer会返回Foo.getThing,但它会覆盖返回Number的方法Integer。这很好,因为我们可以在Number使用{{1}}。