Should you use "extends" or "with" keyword for ChangeNotifier? - Flutter
Asked Answered
U

4

34

I have seen several examples of a model extending ChangeNotifier using both 'extends' and 'with' keywords. I am not sure what the difference is.

class myModel extends ChangeNotifier {...}

class myModel with ChangeNotifier {...}

What is the difference between those two? Which one should I use?

Unwinking answered 20/6, 2019 at 6:31 Comment(1)
see this and thisBitolj
O
38

You can use either extends (to inherit) or with (as a mixin). Both ways give you access to the notifyListeners() method in ChangeNotifier.

Inheritance

Extending ChangeNotifier means that ChangeNotifier is the super class.

class MyModel extends ChangeNotifier {
  
  String someValue = 'Hello';
  
  void doSomething(String value) {
    someValue = value;
    notifyListeners();
  }
}

If your model class is already extending another class, then you can't extend ChangeNotifier because Dart does not allow multiple inheritance. In this case you must use a mixin.

Mixin

A mixin allows you to use the concrete methods of the mixin class (ie, notifyListeners()).

class MyModel with ChangeNotifier {
  
  String someValue = 'Hello';
  
  void doSomething(String value) {
    someValue = value;
    notifyListeners();
  }
}

So even if your model already extends from another class, you can still "mix in" ChangeNotifier.

class MyModel extends SomeOtherClass with ChangeNotifier {
  
  String someValue = 'Hello';
  
  void doSomething(String value) {
    someValue = value;
    notifyListeners();
  }
}

Here are some good reads about mixins:

Octosyllabic answered 26/10, 2019 at 9:39 Comment(2)
So, why Flutter provide extending, while we always can use mixin?Stockist
You can mixin any class. A class doesn't have to be annotated as a mixin to be a Mixin.Refreshing
L
8

extends is used to inherit a class
with is used to use class as a mixin

Refer here to understand difference between mixin and inheritence: https://mcmap.net/q/18907/-mixin-vs-inheritance

Refering to ChangeNotifier, the docs says

A class that can be extended or mixed in that provides a change notification API using VoidCallback for notifications.

Hence you can inherit it as well as use it as a mixin

Lapful answered 20/6, 2019 at 7:0 Comment(0)
C
0

I think this has to do with legacy support. The mixin keyword was introduced in Dart 2.1.0. According to the documentation, you should AVOID mixing in a type that isn’t intended to be a mixin:

For compatibility reasons, Dart still allows you to mix in classes that aren’t defined using mixin. But, that’s risky. If the author of the class doesn’t intend the class to be used as a mixin, they might change the class in a way that breaks the mixin restrictions. For example, if they add a constructor, your class will break.

If the class doesn’t have a doc comment or an obvious name like IterableMixin, assume you cannot mix in the class if it isn’t declared using mixin.

As Dart does not allow multiple inheritances the ChangeNotifier API allows it to be mixed in. As the documentation states:

A class that can be extended or mixed in that provides a change notification API using VoidCallback for notifications.

IMHO to be aligned to the language specification Flutter should change the ChangeNotifier, separating those reusable implementations into Mixin Classes. At least the Dart documentation makes me think this is something that could not be supported anymore in a future release [the mix in of a non mixin class].

There are lot of discussions around this:

Cardinalate answered 8/1, 2022 at 11:1 Comment(0)
N
0

in Provider, Both allow to use notifyListeners(),But

Extend means that (ChangeNotifier) is superclass, Mixin allows using the methods from (ChangeNotifier) class

also You can extend one class But can mixin more than one class

This is a good short article about difference:
Should use Extends or Mixin | Flutter Tips

Nadbus answered 20/4, 2022 at 11:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.