0

对不起,我真的不知道如何为这个问题做标题;也许我不知道我想做的事情有一个名字,但我可以用一些代码来解释它:

猜猜你有一个类,不幸的是既没有复制构造函数也没有公共静态复制方法。

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 中做到这一点?

4

4 回答 4

3

要么更改 A 和 B 的设计,以便能够将 A 转换为 B(如果它甚至有意义:您如何将狗变成 dalmatian?),或者使用组合而不是继承:

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();
    }

    // ...
}
于 2011-03-23T23:06:35.130 回答
1

在 java 中,没有实现clone()using operator new。我希望你能控制原始的 Java 类——它没有遵循最佳实践。

相反,您调用super.clone()它会神奇地返回正确类型的对象,并将先前克隆方法的结果应用于它。

请参阅如何正确覆盖克隆方法

于 2011-03-23T23:06:15.080 回答
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 更改它的返回类型(此功能称为协变返回类型):

B someFn(x, y, z){
   ...
}
于 2011-03-23T23:08:23.440 回答
0

不幸的是,剩下的唯一方法是模仿我需要的功能的完整包装器,购买时会产生一些性能开销。

完全愚蠢的是,没有办法为克隆提供一个类来克隆……</p>

于 2012-11-22T22:56:39.277 回答