Home > Mobile >  Instantiating derived class Object in Base-Class main-Method in Java
Instantiating derived class Object in Base-Class main-Method in Java

Time:02-03

I have got the following problem (I simplified it).

I programmed an abstract class, like this:

public abstract class Calculation{
    abstract public int multiply(int x);
    public final static void main(String[] args){
        for(int i=0; i<args.length; i  ){
            int x = Integer.parseInt(args[i]);
            // I want to call the Method multiply here. 
            // Therefore I need an object here!
        }
    }
}

My abstract class has a main-Method which should evaulate my args and then call the method multiply. Now I want to make some other classes like

public class MOne extends Calculation{
    public int multiply(int x){
        return x;
    }
}
public class MTwo extends Calculation{
    public int multiply(int x){
        return 2*x;
    }

}
public class MThree extends Calculation{
    public int multiply(int x){
        return 3*x;
    }

}

If I call on the console:

java MOne 5
java MTwo 5
java MThree 5

I want java to print 5,10 and 15.

Sadly I don't know how to instanciate the MOne-class respectivly MTwo and MThree in the Calculation-class. Does anyone know, how to make it?

CodePudding user response:

It's possible but expensive because you have to search all classes on the classpath to find those that extend Calculation. A good tool for this is ClassGraph.

Try this code:

List<Class<Calculation>> calculations;
try (ScanResult scanResult = new ClassGraph().enableClassInfo().scan()) {
    calculations = scanResult
        .getSubclasses(Calculation.class.getName())
        .loadClasses(Calculation.class);
}
for(Class<Calculation> calculation : calculations) {
    Calculation calculationInstance = calculation.newInstance(); // needs null constructor
    System.out.println("Java "   calculation.getName()   " "   calculationInstance.multiply(5));
}

CodePudding user response:

Try this. You may need to find the equivalent to sun.java.command for non-Oracle JVM.

public abstract class Calculation {
    abstract public int multiply(int x);

    public final static void main(String[] args)
            throws ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
            InstantiationException, NoSuchMethodException, SecurityException {
    String className = System.getProperty("sun.java.command").split(" ")[0]; // Oracle JVM only
    Class<?> loadedClass = Class.forName(className);
    Method multiplyMethod = loadedClass.getMethod("multiply", int.class);
    Object newInstance = loadedClass.newInstance();

    for(int i=0; i<args.length; i  ){
        int x = Integer.parseInt(args[i]);

        System.out.println("java "   "className "  multiplyMethod.invoke(newInstance, x));
         
    }  
}

Run it with the name of the inheriting class as the first argument and inheriting and base class on classpath:

java -cp path/to/jar;path/to/mine_class MOne 5
  • Related