Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an instance within Abstract Class using Reflection

Is it possible to create an instance of a derived class in abstract ancestor class using reflection Lets say:

abstract class Base {

public Base createInstance(){
  //using reflection
    Class<?> c = this.getClass();
    Constructor<?> ctor = c.getConstructor();
    return ((Base) ctor.newInstance());
}

}//end Base

class Derived extends Base {

 main(){

new Derived().createInstance()

 }

}

like image 605
Ahmet Karakaya Avatar asked Nov 19 '12 09:11

Ahmet Karakaya


People also ask

How do you create an instance of a class using reflection?

We can use newInstance() method on the constructor object to instantiate a new instance of the class. Since we use reflection when we don't have the classes information at compile time, we can assign it to Object and then further use reflection to access it's fields and invoke it's methods.

Can you create an instance of an abstract class?

Abstract classes cannot be instantiated, but they can be subclassed. When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class.

Can you create an instance of an abstract class in C#?

An abstract class cannot be instantiated.

Is it possible to create an instance of an abstract class in C++?

You can't create an object of an abstract class type. However, you can use pointers and references to abstract class types. You create an abstract class by declaring at least one pure virtual member function. That's a virtual function declared by using the pure specifier ( = 0 ) syntax.


1 Answers

You can do this

public class Derived extends Base {
    public static void main(String ... args) {
        System.out.println(new Derived().createInstance());
    }
}

abstract class Base {
    public Base createInstance() {
        //using reflection
        try {
            return getClass().asSubclass(Base.class).newInstance();
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

prints

Derived@55fe910c

A more common pattern is to use Cloneable

public class Derived extends Base {
    public static void main(String ... args) throws CloneNotSupportedException {
        System.out.println(new Derived().clone());
    }
}

abstract class Base implements Cloneable {
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

prints

Derived@8071a97

However, the need to use either should be avoided. Usually there is another way to do what you need so that base doesn't not implicitly depend on derived.

like image 158
Peter Lawrey Avatar answered Sep 29 '22 06:09

Peter Lawrey