我有一组用于存储数据的类,我目前正在尝试实现深层复制机制。为此,我想在我的抽象类中定义一个方法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,但这似乎不对。
有没有一种干净的方法来实现这一目标?
答案 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}}。