11

Duplicate method behavior

The code, here as a Gist, will print e. If I remove the override, i.e. remove output from Baz, it will print w from Bar.
This leads me to the conclusion that the method "priority" is own class -> mixin -> super class.

If I add more mixins, e.g. like this:

mixin Zoo {
  output() {
    print('j');
  }
}

class Baz extends Foo with Bar, Zoo {
// ...

Now, the output is j. If I swap around Bar and Zoo:

class Baz extends Foo with Zoo, Bar {
// ...

Now, the outpt is w again.
Consequently, I would define the priority like this: own class -> last mixin -> nth-last mixin -> super class.

Question

Is there any way for me to control this behavior, i.e. call the super call method even when a mixin has a method with the same name?

Why

You might be askin why I would want to do this and not just rename the methods.
Well, in Flutter all State's have a dispose method and if I have a mixin that has dispose method as well, it will break the State's functionality because the mixin's dispose method takes priority as illustrated above.

Additional notes

super.output will call the mixin method as well, which is why that does not work. You can try adding the following constructor to Baz:

Baz() {
  super.output();
}

Even if this worked, it would not help as the dispose method in the Flutter case is called from the outside.

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
  • 1
    That is simply not possible. In any case, it's usually not a good thing to extensively use mixins in widgets. They are not very scalable – Rémi Rousselet Jul 15 '19 at 09:06

1 Answers1

7

In mixins - the order in which the mixins are declared is very important.

When you apply a mixin to a class,

Mixins in Dart work by creating a new class that layers the implementation of the mixin on top of a superclass to create a new class — it is not “on the side” but “on top” of the superclass, so there is no ambiguity in how to resolve lookups source

class A {
  String getMessage() => 'A';
}

class B {
  String getMessage() => 'B';
}

class P {
  String getMessage() => 'P';
}

class AB extends P with A, B {}

class BA extends P with B, A {}

void main() {
  String result = '';

  AB ab = AB();
  result += ab.getMessage();

  BA ba = BA();
  result += ba.getMessage();

  print(result);
}

Both, AB and BA classes extend the P class with A and B mixins but in a different order. All three A, B and P classes have a method called getMessage.

First, we call the getMessage method of the AB class, then the getMessage method of the BA class.

And the output will be BA.

Want to learn more ? Details Explanation ~>

Robin
  • 4,902
  • 2
  • 27
  • 43