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:
-
inheritance
Subclasses can reuse methods and properties from their parent class, but inheritance in JAVA can only be inherited singly.
-
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.
-
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:
- The objects of mixins are classes
- Mixins are far from being an inheritance or an interface, but rather an entirely new feature
- You can mixins multiple classes
- 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:
- Mixins classes can only inherit from Object
- Mixins classes cannot have constructors
- A class can mixins multiple mixins classes
- 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
- 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
- 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