marks
marks

Reputation: 1391

How to set type definitions depending on the extending class in dartlang

Is there a way to declare return types of methods or the object-prefix to be the "extendingClass" like you would do in PHP with the static::class?

So for example:

abstract class AbstractModel {

  // Should return the database-provider for the given model
  dynamic get modelProvider;

  // Save instance to Database - Create new if no ID exists, 
  // else update existing
  dynamic save() {
    if( id == null ) {
      modelProvider.insert(this); 
    } else {
      modelProvider.update(this);
    }
    return this;
  }
}

class ToDo extends AbstractModel {
  ToDoProvider get modelProvider {
    return ToDoProvider;
  }
}

So in this example, obviously AbstractModel does not yet know what the return type of modelProvider will be, but I do know that it will always be the same type for a given child. Also, the return type of the save method would always be the child-class. But when writing it like this I will get an error for overwriting the modelProvider with an invalid return type.

Due to darts javascript-like nature I assume there is no way to actually achieve this like you would in PHP. But then I wonder how to type-save build re-usable code? I am trying to implement a small eloquent like query-scheme for my models so I don't have to write each CRUD method for every model - but I would still like to be precise about the types and not use dynamic everywhere.

So is there a way to do that in dart or am I completely off the track regarding dart standards?

Upvotes: 0

Views: 30

Answers (1)

Pieter van Loon
Pieter van Loon

Reputation: 5648

You can use generics:

abstract class AbstractModel<ChildType extends AbstractModel<ChildType>> {

  // Should return the database-provider for the given model
  ModelProvider<ChildType> get modelProvider;

  // Save instance to Database - Create new if no ID exists, 
  // else update existing
  ChildType save() {
    if( id == null ) {
      modelProvider.insert(this); 
    } else {
      modelProvider.update(this);
    }
    return this;
  }
}

class Model extends AbstractModel<Model> {
}

abstract class ModelProvider<T> {
  void insert(T value);
  void update(T value);
}

class MyModelProvider extends ModelProvider<Model> {
  ...
}

Upvotes: 1

Related Questions