抱歉,我真的不知道如何为这个问题制作标题;也许有一个名字,我试图做什么,我不知道,但我可以用一些代码来解释:
猜猜你有一个类,遗憾的是它既没有复制构造函数也没有公共静态复制方法。
class A
{
private int i; // <- private, cant access
String x; // <- even worse: cant access unless in same pkg!
/* … other stuff, ctor, etc. … */
public A clone()
{
A a = new A();
a.i = i;
a.x = x;
return x;
}
}
进一步猜测,有一些函数可以返回该类的对象:
public static A someFn(x,y,z);
现在问题:我想从该类派生来添加一些功能。不幸的是,我既没有java中的sizeof也没有cc或静态复制方法。
所以当我做一个
class B extends A
{
protected w;
public B clone()
{
/* as usual */
}
}
然后我可以克隆我的B并获得一个新的,但是我怎样才能将返回的A从someFn()转换为B.反正是否要在java中切片相反?如果我克隆它,它仍然是A,我不能逐字段复制它。这在c ++中很简单,但是如何用Java做到这一点?
答案 0 :(得分:3)
更改A和B的设计,以便能够将A转换为B(如果它甚至有意义:你如何将狗变成达尔马提亚狗?),或者使用组合而不是继承:
public class B {
private A a;
private int w;
public B(A a, int w) {
this.a = a;
this.w = w;
}
public int foo() {
return a.foo();
}
// ...
}
答案 1 :(得分:1)
在java中,没有使用运算符clone()
实现new
。我希望你能控制原始的Java类 - 它不遵循最佳实践。
你调用super.clone()
而不是神奇地返回一个正确类型的对象,并将先前克隆方法的结果应用于它。
答案 2 :(得分:1)
首先,你的克隆方法是错误的。它应该是这样的:
public A clone(){
A result = (A)super.clone();
result.i = i;
result.x = x;
return result;
}
B的克隆:
public B clone(){
B result = (B)super.clone():
result.w = w;
return result;
}
你可以在B中有一个构造函数,它接受一个A的实例,从它的A实例中提取它所需的数据,并用它创建B对象。
然后,您可以调用someFn(x,y,z),如:
B b = new B(someFn(x, y, z))
另外如果someFn不是静态的,你可以为定义它的类编写一个子类,并覆盖someFn改变它的返回类型(这个特性叫做covariant return type):
B someFn(x, y, z){
...
}
答案 3 :(得分:0)
不幸的是,剩下的唯一方法是使用完整的包装器来模仿我需要的功能,并在性能上花费一些开销。
完全愚蠢的是,没有办法为克隆提供一个克隆的类......