I have an abstract class AbstractClass
, and two non-abstract classes that extend it: A
and B
. Both A
and B
have constructors that take in a String
argument. I also have a method that takes in Class<? extends AbstractClass>
and then creates a new instance of it. How can I make it so that all of children of AbstractClass
have a String
in their constructor?
Code in case I wasn't very clear in the explanation:
public abstract class AbstractClass {
// do stuff
}
public class A extends AbstractClass {
public A(String str) {
// do stuff
}
}
public class B extends AbstractClass {
public B(String str) {
// do stuff
}
}
// this is stuff in other places
public void instantiateClass(Class<? extends AbstractClass> obj) {
AbstractClass object = obj.newInstance("blah"); // Error: Expected 0 arguments but found 1
// do stuff
}
instantiateClass(A.class);
instantiateClass(B.class);
You can't. There is no way to require a constructor to have any arguments.
However, you pass a Function<? super String, ? extends AbstractClass>
instead of a Class<? extends AbstractClass>
: that way, you have to supply a thing which will accept a single String
parameter, even if that's not specifically a constructor:
public void instantiateClass(Function<? super String, ? extends AbstractClass> fn) {
AbstractClass object = fn.apply("blah");
// do stuff
}
instantiateClass(A::new);
instantiateClass(B::new);
and if you have a class whose constructor doesn't take a single String
parameter:
public class C extends AbstractClass {
public C() {
// do stuff
}
}
then instantiateClass(C::new)
wouldn't compile; but instantiateClass(unused -> new C())
would.