Следует ли использовать ключевое слово "extends" или "with" для ChangeNotifier? - флаттер
Я видел несколько примеров модели, расширяющей ChangeNotifier, использующей оба ключевых слова "extends" и "with". Я не уверен, в чем разница.
class myModel extends ChangeNotifier {...}
class myModel with ChangeNotifier {...}
В чем разница между этими двумя? Какой я должен использовать?
4 ответа
Вы можете использовать либо extends
(наследовать) или with
(как миксин). Оба способа дают вам доступ кnotifyListeners()
метод в ChangeNotifier
.
Наследование
Расширение ChangeNotifier
Значит это ChangeNotifier
это суперкласс.
class MyModel extends ChangeNotifier {
String someValue = 'Hello';
void doSomething(String value) {
someValue = value;
notifyListeners();
}
}
Если ваш класс модели уже расширяет другой класс, вы не можете расширить ChangeNotifier
потому что Дарт не допускает множественного наследования. В этом случае вы должны использовать миксин.
Mixin
Примесь позволяет вам использовать конкретные методы класса миксина (т. Е. notifyListeners()
).
class MyModel with ChangeNotifier {
String someValue = 'Hello';
void doSomething(String value) {
someValue = value;
notifyListeners();
}
}
Таким образом, даже если ваша модель уже является наследником другого класса, вы все равно можете "смешать" ChangeNotifier
.
class MyModel extends SomeOtherClass with ChangeNotifier {
String someValue = 'Hello';
void doSomething(String value) {
someValue = value;
notifyListeners();
}
}
Вот несколько полезных статей о миксинах:
extends
используется для наследования классаwith
используется для использования класса в качестве mixin
Обратитесь сюда, чтобы понять разницу между mixin и наследованием: /questions/11318738/mixin-protiv-nasledovaniya/11318752#11318752
Ссылаясь на ChangeNotifier, документы говорят
Класс, который можно расширять или смешивать, предоставляя API уведомлений об изменениях, используя VoidCallback для уведомлений.
Следовательно, вы можете наследовать и использовать его как миксин
в Provider оба позволяют использовать notifyListeners(), но
Расширение означает, что (ChangeNotifier) является суперклассом,Mixin позволяет использовать методы из класса (ChangeNotifier).
также Вы можете расширить один класс, но можете смешивать более одного класса
Это хорошая короткая статья о разнице:
следует использовать расширения или примеси | Советы по флаттеру
Я думаю, что это связано с устаревшей поддержкой. Ключевое слово mixin было введено в Dart 2.1.0. Согласно документации, вам следует ИЗБЕГАТЬ смешивания типов, которые не предназначены для использования в качестве примесей :
Из соображений совместимости Dart по-прежнему позволяет вам смешивать классы, которые не определены с помощью миксина. Но это рискованно. Если автор класса не предполагает, что класс будет использоваться в качестве примеси, он может изменить класс таким образом, чтобы нарушить ограничения примеси. Например, если они добавят конструктор, ваш класс сломается.
Если класс не имеет комментария документа или очевидного имени, такого как IterableMixin, предположим, что вы не можете смешивать в классе, если он не объявлен с помощью mixin.
Поскольку Dart не допускает множественного наследования, API ChangeNotifier позволяет смешивать его. Как указано в документации:
Класс, который можно расширить или смешать, который предоставляет API уведомлений об изменениях, использующий VoidCallback для уведомлений.
ИМХО, чтобы соответствовать спецификации языка, Flutter должен изменить ChangeNotifier, разделив эти повторно используемые реализации на классы Mixin. По крайней мере, документация Dart заставляет меня думать, что это больше не может поддерживаться в будущем выпуске [примесь класса без примеси].
Вокруг этого много дискуссий: