Как установить определения типов в зависимости от расширяемого класса в дартланге

#flutter #dart #inheritance

#flutter #dart #наследование

Вопрос:

Есть ли способ объявить возвращаемые типы методов или префикс объекта «extendingClass», как вы бы сделали в PHP с static::class помощью?

Так, например:

 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;
  }
}
  

Итак, в этом примере, очевидно AbstractModel , еще не известно, каким будет возвращаемый тип modelProvider , но я знаю, что он всегда будет одного и того же типа для данного дочернего элемента. Кроме того, возвращаемым типом save метода всегда будет дочерний класс. Но при написании этого так, я получу сообщение об ошибке из-за перезаписи modelProvider с недопустимым типом возвращаемого значения.

Из-за javascript-подобной природы darts я предполагаю, что на самом деле нет способа добиться этого, как в PHP. Но тогда мне интересно, как сохранить тип, построить повторно используемый код? Я пытаюсь реализовать небольшую схему запросов eloquent like для своих моделей, поэтому мне не нужно писать каждый метод CRUD для каждой модели, но я все равно хотел бы быть точным в отношении типов и не использовать dynamic везде.

Итак, есть ли способ сделать это в dart или я полностью сбился с пути в отношении стандартов dart?

Ответ №1:

Вы можете использовать обобщения:

 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> {
  ...
}