Search code examples
iosobjective-cinitializationshinobi

How can I define a variable which could initialise from two different classes?


Sorry about the slightly vague question title but I found it very difficult to get it straight in my head myself.

The issue here is that I have two different dataSources I might be initialising and loading data from. Depending on the data changes which dataSource I need.

The problem I am having is how to define a variable of that dataSource when it could come from two different classes.

If I define them in my interface:

BColumnChartDataSource * chartDatasource = [[BColumnChartDataSource alloc] initWithExercise:_exercise];
BDoubleColumnChartDataSource * chartDatasource = [[BDoubleColumnChartDataSource alloc] initWithExercise:_exercise];

Then it obviously doesn't like them being called the same thing.

If I try to put them in an if statement then they aren't available outside the logic statement

if (_exercise.unitTypeLinks.count < 2) {
    BColumnChartDataSource * chartDatasource = [[BColumnChartDataSource alloc] initWithExercise:_exercise];
    }
else {
    BDoubleColumnChartDataSource * chartDatasource = [[BDoubleColumnChartDataSource alloc] initWithExercise:_exercise];
}

Eventually I want to put them into a statement like this so I could put an if statement into every one of these but it is an awfully verbose way which might take more time if I add more dataSources.

// Get the exercise event list for our clicked exercise
_exerciseEventList = [chartDatasource getExerciseEventList];

I think I must be missing something obvious here so thank you for any help you can give


Solution

  • You should create create a base class, and inherit both of those classes with the base class.

    @interface BDataSource : NSObject
    @end
    
    @interface BColumnChartDataSource : BDataSource
    //your custom implementation here
    @end
    
    @interface BDoubleColumnChartDataSource : BDataSource
    //your custom implementation here
    @end
    

    After that you can initialise your datasource like this

    BDataSource *dataSource = nil;
    
    if (_exercise.unitTypeLinks.count < 2) {
        dataSource = [[BColumnChartDataSource alloc]     initWithExercise:_exercise];
    }
    else {
        dataSource = [[BDoubleColumnChartDataSource alloc] initWithExercise:_exercise];
    }