Max888
Max888

Reputation: 3760

Class constructor which allows different subtypes as arguments

I am trying to create a class which where the constructor can accept a List, the elements of which must be instances of a subclass of a specific class. Below is a minimal example of what I am working on. I would like the DataSet constructor to accept any list of instances of a subclass of Column i.e. IntegerColumn or DoubleColumn. However, the code below will only accept List<Column> and not List<IntegerColumn> and List<DoubleColumns>, and creates the error: The element type 'DoubleColumn' can't be assigned to the list type 'Column'.. Is it possible to specify that the DataSet constructor can accept a list of any subclass of Column?

class Column {
  List data;
  String name;
}

class IntegerColumn {
  List<int> data;
  String name = 'col1';
  IntegerColumn(this.data);
}

class DoubleColumn {
  List<double> data;
  String name = 'col2';
  DoubleColumn(this.data);
}

class DataSet {
  Map<String, Column> columns;
  DataSet(List<Column> columns) {
    Map<String, Column> namedColumns = {};
    for (Column column in columns) {
      namedColumns[column.name] = column;
    }
    this.columns = namedColumns;
  }
}

void main() {
  DataSet dataSet = DataSet([
    IntegerColumn([1, 2, 3]), // The element type 'DoubleColumn' can't be assigned to the list type 'Column'.
    DoubleColumn([1.1, 2.2, 3.3])
  ]);
  print(dataSet);
}

Upvotes: 0

Views: 32

Answers (2)

julemand101
julemand101

Reputation: 31209

I whould do something like this which are more type safe than the solution from pedro pimont:

abstract class Column<T> {
  List<T> data;
  String name;
}

class IntegerColumn implements Column<int> {
  List<int> data;
  String name = 'col1';
  
  IntegerColumn(this.data);
}

class DoubleColumn implements Column<double> {
  List<double> data;
  String name = 'col2';
  
  DoubleColumn(this.data);
}

class DataSet {
  Map<String, Column> columns;
  
  DataSet(List<Column> columns) {
    Map<String, Column> namedColumns = {};
    for (Column column in columns) {
      namedColumns[column.name] = column;
    }
    this.columns = namedColumns;
  }
}

void main() {
  DataSet dataSet = DataSet([
    IntegerColumn([1, 2, 3]),
    DoubleColumn([1.1, 2.2, 3.3])
  ]);
  
  print(dataSet);
}

Upvotes: 3

pedro pimont
pedro pimont

Reputation: 3074

To make a DoubleColumn into a Column you have to extend it.

class Column {
      List<dynamic> data;
  String name;
  Column(this.data);
}

class IntegerColumn extends Column {
  

  String name = 'col1';
  IntegerColumn(List<int> data) : super(data);
}

class DoubleColumn extends Column {
  

  String name = 'col2';
  DoubleColumn(List<double> data) : super(data);
}

class DataSet {
  Map<String, Column> columns;
  DataSet(List<Column> columns) {
    Map<String, Column> namedColumns = {};
    for (Column column in columns) {
      namedColumns[column.name] = column;
    }
    this.columns = namedColumns;
  }
}

void main() {
  DataSet dataSet = DataSet([
    IntegerColumn([
      1,
      2,
      3
    ]), // The element type 'DoubleColumn' can't be assigned to the list type 'Column'.
    DoubleColumn([1.1, 2.2, 3.3])
  ]);
  print(dataSet);
}

Upvotes: 1

Related Questions