Расширение класса только одним фабричным конструктором

Мне было интересно, что является лучшим способом продлить CustomEvent класс, класс, который имеет только один фабричный конструктор. Я попытался сделать следующее и столкнулся с проблемой с супер-конструктором:

class MyExtendedEvent extends CustomEvent {
  int count;

  factory MyExtendedEvent(num count) {
    return new MyExtendedEvent._internal(1);
  }

  MyExtendedEvent._internal(num count) {
    this.count = count;
  }
}

но я не могу заставить его работать. Я всегда сталкиваюсь с:

неразрешенный неявный вызов супер-конструктора 'CustomEvent()'

Если я попытаюсь изменить внутренний конструктор:

MyExtendedEvent._internal(num count) : super('MyCustomEvent') {
  this.count = count;
}

Я заканчиваю с:

'разрешен неявный вызов супер-конструктора'CustomEvent()''.

Я не уверен, что я делаю неправильно, но я думаю, проблема в том, что CustomEvent имеет только один конструктор, который является конструктором фабрики (как говорит доктор - http://api.dartlang.org/docs/releases/latest/dart_html/CustomEvent.html)

Каков наилучший способ продлить CustomEventили какой-нибудь класс этой формы?

4 ответа

Вы не можете напрямую расширять класс с помощью конструктора фабрики. Однако вы можете реализовать класс и использовать делегирование для имитации расширения.

Например:

class MyExtendedEvent implements CustomEvent {
  int count;
  final CustomEvent _delegate;

  MyExtendedEvent(this.count, String type) :
    _delegate = new CustomEvent(type);

  noSuchMethod(Invocation invocation) =>
      reflect(_delegate).delegate(invocation);
}

NB: я использовал рефлексию здесь, чтобы упростить фрагмент кода. Лучшей реализацией (в отношении производительности) было бы определение всех методов, таких как method1 => _delegate.method1()

К сожалению, вы не можете расширить класс, если он имеет только фабричные конструкторы, вы можете только реализовать его. Это не будет хорошо работать с CustomEvent, так как это тип DOM, и поэтому он имеет только фабричные конструкторы: браузер должен создавать эти экземпляры, объект Dart - просто оболочка. Если вы попытаетесь реализовать CustomElement и запустить его, вы, вероятно, получите ошибку.

Теперь вы можете использовать extension функция Dart (из Dart 2.7), чтобы получить аналогичное поведение, если вы просто хотите добавить некоторые методы в существующий класс.

extension MyExtensionEvent on CustomEvent {
  void increaseCount() => count++;
}

а затем, когда вы хотите использовать недавно созданное расширение, вы просто импортируете его, а затем вызываете экземпляр исходного класса, но с одним из ваших недавно созданных методов:

import event_extension.dart

final event = CustomEvent(1);
event.increaseCount();

Если в классе есть только factory constructors(названный или неназванный) не может быть использован для расширения. (Но вы можете использовать этот класс для implement подклассы)

Поэтому, если вы хотите расширить класс суперклассом, суперкласс должен иметь хотя бы один генеративный конструктор.

Другие вопросы по тегам