How to create instance of subclass with constructor from super class

后端 未结 4 2164
时光取名叫无心
时光取名叫无心 2021-02-19 00:51

I\'d like to create a registry for classes which are subclasses of a super class. The classes are stored in a map which acts as registry. A class is picked from the registry dep

4条回答
  •  眼角桃花
    2021-02-19 01:26

    1. A superclass has no knowledge of its children.
    2. Constructors are not inherited.

    Therefore, without making assumptions about the subclass ctor, you cannot write the code that you want.

    So what can you do? Use an Abstract Factory pattern.

    We can create an interface Factory:

    @FunctionalInterface
    public interface SuperclassFactory {
        Superclass newInstance(Object o);
    }
    

    You could create more than one method on the Factory, but that would make it less neat for lambdas.

    Now you have a Map, and populate it:

    Map registry = new HashMap<>();
    registry.put(0, SubClass1::new);
    registry.put(1, SubClass2::new);
    

    So, in order to use this Map you simply do:

    for(final Map.Entry e: registry.entrySet()) {
        //...
        final BaseClass instance = e.getValue().newInstance(e.getKey());
        //...
    }
    

    If your subclass does not have the appropriate ctor, this code will not compile as there will be no ctor reference that can be used. This is Good Thing (TM). In order to compile with the current Subclass2 you would need to use:

    registry.put(1, obj -> new SubClass2());
    

    So now we have:

    1. Lost the reflection
    2. Acquired compile time type safety
    3. Lost the ugly cast (although that was through misuse of reflection)

    N.B. loop through a Map's entrySet() not its keySet().

提交回复
热议问题