Tobias Johansson
Tobias Johansson

Reputation: 376

abstract class implements Cloneable; abstract Object clone()

Lets say I have this class:

public abstract class AbstractFoo implements Cloneable {

    public abstract Object clone();

}

And the subclass:

public class Foobar extends AbstractFoo {

    @Override
    public Object clone() {
        try {
            Foobar c = (Foobar) super.clone();
            /* some operations */
            return c;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }

}

I know this is not possible, but I think you understand what I want. The subclass would work if Foobar implemented Cloneable and did not extend AbstractFoo. I think what I would want but is not allowed is this:

Foobar c = (Foobar) super.super.clone();

The subclass would work if Foobar implemented Cloneable and did not extend AbstractFoo.

How could I do "the same" but with the extended abstract class?

Upvotes: 3

Views: 3705

Answers (2)

Tobias Johansson
Tobias Johansson

Reputation: 376

Would this work?

public abstract class AbstractFoo implements Cloneable {

    public abstract Object clone();

    // Enables subclasses to call "super.super.clone()"
    public Object superDotClone() throws CloneNotSupportedException {
        return super.clone();
    }

}

With the subclass:

public class Foobar extends AbstractFoo {

    @Override
    public Object clone() {
        try {
            Foobar c = (Foobar) super.superDotClone();
            /* some operations */
            return c;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }

}

Upvotes: 2

Roman Nikitchenko
Roman Nikitchenko

Reputation: 13046

OK, you have MUCH more wide problem. I must say you'r screwed. Here is related question: Force every class of an inheritance chain to override an abstract method

The main problem any abstract class which implements Cloneable actually relies on Object.clone(). So it is in general problem without solution but ...

PROPOSED SOLUTION:

I've got one idea from here: Mandatory cloneable interface in Java

public interface Modifiable<T extends Modifiable<T>> extends Cloneable {
    T clone();
}

public class Foo implements Modifiable<Foo> {
    public Foo clone() { //this is required
        return null; //todo: real work
    }
}

MUCH better than anything posted here.

PREVIOUS GUESSINS:

Maybe your idea is not 100% clear but is this approach suitable?

public abstract class AbstractFoo implements Cloneable {

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}

And then...

public class Foobar extends AbstractFoo {

    @Override
    public Object clone() {
        try {
            Foobar c = (Foobar) super.clone();
            /* some operations */
            return c;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }

}

Hmmm... if you need to force descendants to impleement clone... actually I don't like smell of this idea but why not do something like this in this case?

public abstract class AbstractFoo implements Cloneable {

    public Object clone() throws CloneNotSupportedException {
        return cloneMe();
    }

    abstract protected Object cloneMe();

}

And finally ... bad, but you are asking about this ;-).

public class Foobar extends AbstractFoo {

    @Override
    public Object cloneMe() {
        try {
            Foobar c = (Foobar) super.clone();
            /* some operations */
            return c;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }

}

Upvotes: 2

Related Questions