3

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?

Tobias Johansson
  • 378
  • 4
  • 11
  • I don't understand. What do you expect `super.clone();` to do? What do you want it to do? – Sotirios Delimanolis Feb 08 '15 at 16:23
  • Could you explain what it is you want to do and what isn't working? A more descriptive title would be useful as well. – Jeroen Vannevel Feb 08 '15 at 16:24
  • This code would work if Foobar implemented Cloneable and did not extend AbstractFoo. How could I do "the same" but with the extended abstract class? – Tobias Johansson Feb 08 '15 at 16:27
  • Again, what do you expect `super.clone();` to do? – Sotirios Delimanolis Feb 08 '15 at 16:34
  • Without the extended class and with implemnts Cloneable - a clone. – Tobias Johansson Feb 08 '15 at 16:35
  • So you want to force subclasses of `AbstractFoo` to implement `clone`, but you want them to use the default `Object#clone` implementation? – Sotirios Delimanolis Feb 08 '15 at 16:41
  • @ Sotirios Delimanolis "What do you expect super.clone(); to do?" - First off, if you have a question, you should actually post your own question. It's inappropriate to try too hijack someone else's question. Second, the expected behavior of #clone is laid out in the Java specification, and if you don't have this prerequisite knowledge then you're not going to be able to contribute to the discussion in any meaningful way. – Steven Byks Jan 25 '17 at 00:21

2 Answers2

2

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

}
Community
  • 1
  • 1
Roman Nikitchenko
  • 12,800
  • 7
  • 74
  • 110
  • Yes that would work. The problem here is that i want an abstract class that implements Cloneable with _public abstract Object clone()_. So the abstract class will force subclasses to implement a clone() method. I guess this is not possible? – Tobias Johansson Feb 08 '15 at 16:42
  • As class is abstract nobody will notes the difference (if method is abstract). Huh? – Roman Nikitchenko Feb 08 '15 at 16:44
  • The diffrence will lay in that subclasses does not get forced to implement a clone() method. – Tobias Johansson Feb 08 '15 at 16:50
  • Does update suit you? My understanding you're trying to invent bike... but it is periodically needed in Java :-). – Roman Nikitchenko Feb 08 '15 at 16:51
  • Please check solution with `Modifiable` and original link - should be suitable for you. Not exactly what you'ver requested but actually pretty nice. – Roman Nikitchenko Feb 08 '15 at 17:06
2

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

}
Tobias Johansson
  • 378
  • 4
  • 11
  • Ouch.. looks similar but I'm considering which solution (this or mine) is more dirty. Actually this problem is about forcing descendants to override something that is already implemented. – Roman Nikitchenko Feb 08 '15 at 17:00
  • I like mine better because I want AbstractFoo to implement an interface that requests a clone() method. – Tobias Johansson Feb 08 '15 at 17:04