Scottie
Scottie

Reputation: 23

Cloning an instantiated abstract class

Instantiate an abstract class. -> Duplicate it, preserving the implementation of the abstract method.

    public abstract class Foo{… 

    public int myVar;

    public abstract void do();

     }//Foo

elsewhere in package:

public class Gha{ … 

    Foo testFoo = new Foo{

        @Override
        public void do(){
            Log.i("" , "this is a special Foo"); //executable process
        }//do

    }//testFoo
    …
}//Gha

Can I copy testFoo in a way that copies testFoo’s .do() method body for the new Foo?

Upvotes: 1

Views: 1621

Answers (2)

Paul Boddington
Paul Boddington

Reputation: 37655

You could use clone. The use of this method is widely discouraged, but it does work.

For example:

public abstract class Foo implements Cloneable {

    private int a;
    private String b;

    public Foo(int a, String b) {
        this.a = a;
        this.b = b;
    } 

    public abstract void run();

    public int getA() { return a; }

    public String getB() { return b; }

    @Override
    public final Foo clone() {
        try {
            return (Foo) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError(); // Can't happen
        }
    }
}

Then, you can do:

Foo original = new Foo(3, "bar") {
    @Override
    public void run() {
        System.out.println("Hello, world!");
    }
};
Foo copy = original.clone();
System.out.println(copy.getA());
System.out.println(copy.getB());
copy.run();
System.out.println(copy == original);

The output is:

3
bar
Hello, world!
false

An alternative is to use Serializable.

public abstract class Foo implements Serializable {

    private int a;
    private String b;

    public Foo(int a, String b) {
        this.a = a;
        this.b = b;
    }

    public abstract void run();

    public int getA() { return a; }

    public String getB() { return b; }

    public final Foo copy() {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            new ObjectOutputStream(baos).writeObject(this);
            return (Foo) new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())).readObject();
        } catch (Exception e) {
            throw new AssertionError(); 
        }
    }
}

With this version, replace clone by copy and you'll get the same result.

Upvotes: 2

zgc7009
zgc7009

Reputation: 3389

You can do this...

public class TestFoo extends Foo{

    private static String TAG = TestFoo.class.getSimpleName();

    @Override
    public void do(){
        Log.i(getTag() , “this is a special Foo”); //executable process
    }

    protected String getTag(){
        return TAG;
    }
}

And then instantiate TestFoo objects that will perform do(). If you want a separate Tag for each instance you can override the getTag() function in the instanted class. Not sure if this is what you need but a lot easier to explain than a comment :P

NOTE

If this is something you would be doing in a lot of places, and you don't want to subclass all over the place (mentioned in the comments) please look at Paul Boddington's answer, particularly the copy portion.

Upvotes: 1

Related Questions