Search code examples
javaabstractimplementscoding-efficiency

Elegant way to implement abstract class


I have an abstract class with a single abstract method; and a number of implementing classes (about 6).

The method returns an object that "needs" two parameters.

However, in some cases, only one of the two parameters is required.

Is there an elegant way to implement this case? (instead of return this parameter as empty)

public class NormResult {
    protected List<String> normWords;
    protected  List<String> unNormWords;

    public NormResult(List<String> normWords,List<String> unNormWords) {
        this.normWords = normWords;
        this.unNormWords = unNormWords;
    }

    public NormResult(List<String> normWords) {
        this.normWords = normWords;
        this.unNormWords =  Collections.emptyList();
    }
}

public abstract class AbstractNormalizer {
    protected abstract List<NormResult> doNorm();
}

public class FirstNormImpl extends AbstractNormalizer {
    protected List<NormResult> doNorm() {
        List<String> normWords = new ArrayList<>(5);
        List<String> unNormWords = new ArrayList<>(7);

        NormResult result = new NormResult(normWords, unNormWords);
        return result;      
    }
}

public class SecondNormImpl extends AbstractNormalizer {
    protected List<NormResult> doNorm() {
        List<String> normWords = new ArrayList<>(8);    
        NormResult result = new NormResult(normWords);
        return result;
    }
}

Solution

  • if you do this to members final:

     protected final List<String> normWords;
     protected final List<String> unNormWords;
    

    then in the constructor you have to initialize them both... then you can set to an empty collection or a null reference the one you dont have/need

    and your overloaded constructor can look like:

    public NormResult(List<String> normWords, List<String> unNormWords) {
        this.normWords = normWords;
        this.unNormWords = unNormWords;
    }
    
    public NormResult(List<String> normWords) {
        this(normWords, Collections.emptyList());
    }