Question

Sorry, i really dont know how to make a headline for that question; maybe there is a name for what im trying to do that i dont know, but i can explain it with some code:

Guess you have a class that unfortunately neither has a copy-constructor nor a public static copy method.

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

Guess further, there is some function that returns an object of that class:

public static A someFn(x,y,z);

Now the problem: I want to derive from that class to add some functionality. Unfortunately, i neither have a sizeof in java nor a cc or static copy method.

So when i do a

class B extends A
{
    protected w;
    public B clone()
    {
       /* as usual */
    }
}

then i can clone my B and get a new one, but how can i convert the returned A from someFn() into a B. Is there anyway to do the opposite of slicing in java? if i clone it, it's still an A, and i cant copy it field by field. This is all simple in c++, but how to do this in Java?

Was it helpful?

Solution 4

Unfortunately, the only way left was a complete wrapper mimicing the functionality i needed, buyed with some overhead in performance.

Its completly stupid that there is no way to provide a class for clone to clone into…

OTHER TIPS

Either change the design of A and B to be able to transform an A into a B (if it's even meaningful : how would you transform a dog into a dalmatian?), or use composition instead of inheritance :

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

    // ...
}

In java, one does not implement clone() using operator new. I hope you have control over the original Java class - it is not adhering to best practices.

You call super.clone() instead which magically returns an object of the correct type, with the results of the previous clone methods applied to it.

See How to properly override clone method.

First, your clone method is wrong. It sould be something like:

public A clone(){
    A result = (A)super.clone();
    result.i = i;
    result.x = x;
    return result;
}

While the clone for B:

public B clone(){
    B result = (B)super.clone():
    result.w = w;
    return result;
}

You could have a constructor in B which takes an instance of A, pulls out the data it requires from that instance of A, and creates the B object with it.

Then, you could call someFn(x,y,z) like:

B b = new B(someFn(x, y, z))

Also if someFn wouldn't have been static, you could have written a subclass for the class that defines it, and override someFn changing it's return type like (this feature is called covariant return type):

B someFn(x, y, z){
   ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top