Super class knowing the type of its children? Surely there is a better way I'm working on a small project that does mathematical calculations based on selected data in a JTable. The goal is to make the program fairly adaptable for adding new mathematical calculations in the future. For reference, some of the current calculations are: calculating the mean (average) of a set of data; calculating the percentile of each item in a set of input data; calculating the least squares linear regression (best fit linear function) for a set of data points.

My current design thought process is that to make things the math utilities flexible, there needs to be a some type of base class for analysis data that serves as input and output to some type of performAnalysis function in a base class for all analysis classes. This lead me to a skeleton design as follows:

public enum AnalysisDataType {
    Scalar,
    Set,
    Map
}

public interface IAnalysisData {
    AnalysisDataType getType();
}

public interface IAnalaysisDataScalar extends IAnalysisData {
    double getValue();
}

public interface IAnalaysisDataSet extends IAnalysisData {
    int getCount();
    IAnalysisData getData(int index);
}

public interface IAnalaysisDataMap extends IAnalysisData {
    IAnalysisData getDomain();
    IAnalysisData getCodomain();
}

public interface IDataAnalysis {
    AnalysisDataType getInputDataType();
    AnalysisDataType getOutputDataType();

    IAnalysisData performAnalysis(IAnalysisData inputData);
}


Then, something for calculating mean would be:

public class DataAnalysisMean implements IDataAnalysis {
    AnalysisDataType getInputDataType() { return AnalysisDataType.Set; }
    AnalysisDataType getInputDataType() { return AnalysisDataType.Scalar; }

    IAnalysisData performAnalysis(IAnalysisData intputData) {

        IAnalysisDataSet inputDataSet = (IAnalysisDataSet)inputData;
        double sum = 0;

        for (int i = 0; i &lt; inputDataSet.getCount(); i++) {
            IAnalysisData dataItem = inputDataSet.getData(i);
            IAnalysisDataScalar dataItem = (IAnalysisDataScalar)dataItem;
            sum += dataItem.getValue();
        }

        return new IAnalysisDataScalar() {
            @Override
            double getValue() {
                return sum / inputDataSet.getCount();
            }

            @Override
            AnalysisDataType getType() {
                return AnalysisDataType.Scalar;
            }
        };
    }
}


I realize a little more work needs to go into "describing" the input and output data items because no where did I mention that the input set contained scalars, but - while I already have an idea how to solve that one - I feel that the whole approach is hackish.

The thought behind this approach is that the code using interfacing with these math utilities could query the IDataAnalysis interface to determine what the expected input and output is and can send the appropriate input as needed and parse the results appropriately. This would allow us to just need to drop-in more functionality at a later time without having to add additional controller logic to tie it in.

I feel like its wrong for a parent class - or interface in this case - to know about its possible children classes (interfaces) through the AnalysisDataType enum and the getType method. As always with OO programming, surely just another layer of abstraction or some type is needed, though perhaps I'm just missing out on some other design pattern that solves this exact problem.

Anyway, if anyone has advice on what I might do to better organize this, I'd much appreciate it. I'd love to hear how wrong my thoughts are and learn a better way.
First, I get some error messages when I put this in the compiler.
I had to replace the anonymous inner class that is returned by performAnalysis with a helper class. I'm not a fan of helper classes like this, so it would be nice if someone else had a better idea.

Second, I'm thinking generics would solve this quite nicely.
I agree that the parent class should not need to know it's child classes, but it can obtain this data; see the methods that I have commented out. I have commented them out because I don't like them, but still want to show that it's possible. I'll admit that using .class is a bit tricky when using generics, because of type erasure. However, as long as the generic types are known at compile time, this should not be a problem.

interface IDataAnalysis&lt;InputType extends IAnalysisData, OutputType extends IAnalysisData&gt; {

//    public Class&lt;?&gt; getInputDataType( );
//    public Class&lt;?&gt; getOutputDataType( );

    OutputType performAnalysis(InputType inputData);
}

public class DataAnalysisMean implements IDataAnalysis&lt;IAnalysisDataSet, IAnalysisDataScalar&gt; {

//    
//    public Class&lt;?&gt; getInputDataType( ) { return IAnalysisDataSet.class; }
//    public Class&lt;?&gt; getOutputDataType( )  { return IAnalysisDataScalar.class; }

public IAnalysisDataScalar performAnalysis(IAnalysisDataSet inputData) {

    IAnalysisDataSet inputDataSet = (IAnalysisDataSet)inputData;
    double sum = 0;

    for (int i = 0; i &lt; inputDataSet.getCount(); i++) {
        IAnalysisData dataItem = inputDataSet.getData(i);
        IAnalysisDataScalar dataItem2 = (IAnalysisDataScalar)dataItem;
        sum += dataItem2.getValue();
    }

    return new HelperClass( inputDataSet, sum );
}

private class HelperClass implements IAnalysisDataScalar
{
    IAnalysisDataSet inputDataSet;
    double sum = 0;

    HelperClass( IAnalysisDataSet inputSet, double sum )
    {
        this.inputDataSet = inputSet;
        this.sum = sum; 
    }

    @Override
    public double getValue() {
        return sum / inputDataSet.getCount();
    }

    @Override
    public AnalysisDataType getType() {
        return AnalysisDataType.Scalar;
    }
   }
}