Search code examples
javaabstract-class

Standardized Constructors Across Subclasses?


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);

Solution

  • 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.