Lets say I have the following setup
an interface
public interface TestInterface {
public void draw();
}
and two implementations
public class Square implements TestInterface {
@Override
public void draw() {
System.out.println("Square");
}
}
and
public class Circle implements TestInterface {
@Override
public void draw() {
System.out.println("Circle");
}
}
Now I can easily do
TestInterface a = new Square();
a.draw();
and I correctly get Square
. Next, I wanted to try out reflection.
Class<?> clazz = null;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Constructor<?> constructor = null;
try {
constructor = clazz.getConstructor();
} catch (NoSuchMethodException | SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Object instance = null;
try {
instance = constructor.newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Method method = null;
try {
method = instance.getClass().getMethod(methodName);
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
method.invoke(instance);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
and for className
as some.package.Square
and methodName
as draw
I again get Square
. Which is correct.
The problem is that my application has access to the interface
but not the actual implementations. Hence I know which methods to invoke, but I have to specify the implemented classes as well and I dont know which package they may reside in. What if I only know the name of the class but not the package?
Is there a way where I can still use the initialization form of
TestInterface a = new <some_parameter>();
a.draw();
Is there a way to generalize it? Or is the approach using reflection that I showed above, the only way to achieve something like this? Lastly, would it make any difference if I used an abstract class instead of an interface?