'Should you use "extends" or "with" keyword for ChangeNotifier? - Flutter

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?



Solution 1:[1]

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:

Solution 2:[2]

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://stackoverflow.com/a/860312/10471480

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

Solution 3:[3]

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:

Solution 4:[4]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Mangaldeep Pannu
Solution 3
Solution 4 Ramy Wahid