0 x00 preface

As an important feature of Flutter, mixins are worth studying

0x01 Mixins definition

Mixins, which means to mixin other functions into a class.

The definition in Dart is:

Mixins are a way of reusing a class’s code in multiple class hierarchies.
Copy the code

Mixins are a way to reuse class code across multiple class hierarchies.

As you can see, the most important function of Mixins is to reuse code. Let’s take a look at JAVA and see how it can reuse code:

  1. inheritance

    Subclasses can reuse methods and properties from their parent class, but inheritance in JAVA can only be inherited singly.

  2. combination

    To reuse code, encapsulated into A class A, let the other classes have the instance of A seems to solve the problem of reusing code, but on the other hand, each class held by A instance is different, how many classes, A total of how much A instance, and on the other hand, even A single case, also is not very convenient to use.

  3. interface

    Define an interface, the class implementation interface, so that although the interface is the same, but the implementation is scattered, reusable code is limited.

So when you want to reuse code in JAVA, there are a lot of limitations.

This is where the concept of mixins comes from. The earliest roots of mixins come from Lisp. Dart was also influenced by Smalltakk, so Dart introduced the concept of mixins.

Wikipedia has the most accurate definition of mixins:

In an object-oriented language, a mixins class is a class that makes its methods available to other classes, but does not need to be a parent class.Copy the code

Mixins are intended to reuse code in a class in a non-inherited manner.

For example, if you have A class A that has A method A () and A method B that also wants to use A () and can’t inherit, then you need to use mixins. Class A is the mixins class, and class B is the class to be mixins. The corresponding Dart code is as follows:

Class A mixins to B

class A {
  String content = 'A Class';

  void a() {print("a");
  }
}

class B with A{

}

B b = new B();
print(b.content);
b.a();
Copy the code

The output is:

A Class
a
Copy the code

Mixins class A to B, B can use A’s attributes and methods, and B has the functions of A, but it needs to be emphasized:

  1. The objects of mixins are classes
  2. Mixins are far from being an inheritance or an interface, but rather an entirely new feature
  3. You can mixins multiple classes
  4. Mixins need to meet certain conditions

0x02 with

Mixins use the keyword with

How to understand with? Is simple:

Inheritance – > extends

mixins -> with

Inheritance, like mixins, is a feature of the language; with and extends are keywords.

0x03 Conditions for using mixins

Because the conditions for mixins are changing with Dart releases, here are the conditions for mixins in Dart2.1:

  1. Mixins classes can only inherit from Object
  2. Mixins classes cannot have constructors
  3. A class can mixins multiple mixins classes
  4. Can mixins multiple classes without breaking the single inheritance of Flutter

0x04 A class can mixins multiple mixins classes

Look at the following code:

class A {
  void a() {print("a");
  }
}

class A1 {
  void a1() {print("a1");
  }
}

class B with A,A1{

}

B b = new B();
b.a();
b.a1();
Copy the code

The output is:

a
a1
Copy the code

However, if the methods of A and A1 are the same, and the order of A and A1 is reversed, and the same method is implemented in the mixins class, look at the following code:

class A {
  void a() {print("a");
  }
}

class A1 {
  void a() {print("a1");
  }
}

class B with A,A1{

}

class B1 with A1,A{

}

class B2 with A,A1{
  void a() {print("b2");
  }
}

class C {
  void a() {print("a1");
  }
}

class B3 extends C with A,A1{

}

class B4 extends C with A1,A{
  
}

class B5 extends C with A,A1{
  void a() {print("b5");
  }
}

B b = new B();
B1 b1 = new B1();
B2 b2 = new B2();
B3 b3 = new B3();
B4 b4 = new B4();
B5 b5 = new B5();



b.a();
b1.a();
b2.a();
b3.a();
b4.a();
b5.a();
Copy the code

What would be the result?

0x05 Implementation principles of mixins

Mixins inDart 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 ambiguityin how to resolve lookups.
Copy the code

In order to

class B3 extends C with A,A1{

}
Copy the code

As an example, it can be decomposed into:

class CA = C with A;
class CAA1 = CA with A1;

class B3 extends CAA1{
    
}
Copy the code

Mixins are not multiple inheritance

Mixins is not a way to get multiple inheritance in the classical sense. Mixins is a way to abstract and reuse a family of operations and state. It is similar to the reuse you get from extending a class, but it is compatible with single-inheritance because it is linear.
Copy the code

So the output is:

a1
a
b2
a1
a
b5
Copy the code

Type 0 x06 mixins

What is the instance type of mixins?

Quite simply, mixins are subtypes of their superclasses, so:

B3 b3 = B3();
print(b3 is C);
print(b3 is A);
print(b3 is A1);
Copy the code

All is true

0x07 on

The on keyword, previously used for a try catch, is used to specify the type of exception.

This time, on can only be used for classes marked by mixins, such as Mixins X on A, which means that mixins X must be implemented or inherited from A. Here A can be either A class or an interface, but it is used differently in mixins.

The syntax of Flutter Dart (1) extends, implements, with

  1. On a class

With inheritance:

lass A {
  void a() {print("a");
  }
}


mixin X on A{
  void x() {print("x");
  }
}


class mixinsX extends A with X{

}
Copy the code
  1. On is an interface:

You need to implement this interface first, and then use MIX

class A {
  void a() {print("a");
  }
}


mixin X on A{
  void x() {print("x");
  }
}

class implA implements A{
  @override
  void a() {
    // TODO: implement a
  }

}

class mixinsX2 extends implA with X{

}
Copy the code