The Dart is introduced

  1. Dart is to Flutter what TypeScript is to Angular
  2. Dart everything is an Object, as are numbers, functions, and null. All objects inherit from Object
  3. Dart parses all code before running, specifying types and compile-time constants to speed up the code
  4. Dart does not include the public, protected, or private keywords. Variables defined by underscores (_) are private variables

The Dart keyword

The abstract abstract class do The import import libraries Super super class
As type Conversion Dynamic type in The switch cycle
assert else Interface Interface (seemingly removed) Sync * & yield Indicates the synchronization generator
Enum enumeration Implements interface Is similar to the instanceof this
Async * identifies an asynchronous generator function Export export Library defines the name of the library Throw an exception
Await for The implementation of the external code is provided externally Mixin (multiple inheritance) true & false
break extends new try & catch
case Factory Identifies the factory constructor null Typedef declares the type of a function
Operator vector class var class final
Part splits the library into multiple Dart files void const finally
A rethrow makes an exception propagatable while continue for
return With cooperate with mixins Covariant prevents error reporting of parameter narrowing changes get & set
default if static Deferred declares a lazy-loaded library

The types and common apis that Dart supports built-in

  • Numbers (has two subclasses of int and double, both derived from numbers)
  • strings
  • booleans
  • lists
  • maps
  • Runes (used to represent Unicode characters in strings)
  • symbols

Define constants

  1. const

Const is assigned at compile time, and const ina class must be defined as static const. (const is implicitly final) Final can only be assigned once during class initialization. Values are not seen at compile time

Common API of num type

Website address: api.dartlang.org/stable/2.5….

  1. IsEven means whether this number isEven
void main(){
  int x = 18;
  print(x.isEven);
}
Copy the code
  1. IsOdd Checks whether it is an odd number

void main(){
  int x = 19;
  print(x.isOdd);
}
Copy the code
  1. ToDouble this is int toDouble

void main(){
  int x = 3;
  print(x.toDouble()); // The result is 3.0
}
Copy the code
  1. . Various mathematical methods (round, floor, ceil, truncate, abs, isInfinite, etc.)

The String used API

Website address: api.dartlang.org/stable/2.5….

  1. Single-line and multi-line strings
// Examples from the official website
'Single quotes';
"Double quotes";
'Double quotes in "single" quotes';
"Single quotes in 'double' quotes";
// Three single quotes
'''A
multiline
string''';
// Three double quotes
"""
Another
multiline
string""";
Copy the code
  1. Use the + sign to concatenate strings
'Dart ' + 'is ' + 'fun! '; // 'Dart is fun! '
Copy the code
  1. Concatenation of adjacent string literals:
'Dart ' 'is ' 'fun! ';    // 'Dart is fun! '
Copy the code
  1. String interpolation
String str = 'yuanchen';
String str2 = 'username is ${str}'; //username is yuanchen
Copy the code
  1. Accessing a string representation of a code unit through an index symbol:
String str = 'yuanchen';
print(str[0]) // 'y'
Copy the code
  1. IsEmpty returns true if the string isEmpty.
  2. IsNotEmpty returns true if this string isNotEmpty.
  3. Length Returns the length of the string
  4. CompareTo roughly means to determine whether the current number is greater than or equal to a specified number
/* * Returns 0 * if the current number is greater than the specified number returns 1 * if the current number is less than the specified number returns -1 */
double a = 2.4;
print(a.compareTo(12)) / / 1
print(a.compareTo(2.4)) / / 0
print(a.compareTo(0)) // -1
Copy the code
  1. Contains Whether contains the specified string
print('yuanchen'.contains('yuan')); // true
Copy the code
  1. IndexOf with JavaScript indexOf
print('yuanchen'.indexOf('u')); / / 1
Copy the code
  1. LastIndexOf Specifies the last occurrence position of the string
print('www.baidu.com'.lastIndexOf('. ')) / / 9
Copy the code
  1. ReplaceAll replaces all matching substrings
const String str = "yuanyuanchen";
 print("New String: ${str.replaceAll('yuanyuan'.'yuan')}"); //yuanchen
Copy the code
  1. Split String to array
  2. SplitMapJoin splits the string, transforms its parts, and then combines them into a new string
const String str = 'a b,c';
// Query ", ", replace "with the return value of onMatch," replace other with the return value of onNonMatch
String str1 = str.splitMapJoin(",",  
  onMatch: (Match match) => "a",
  onNonMatch: (String nonMatch) => "b"
);

print(str1) // a b,c -> bab
Copy the code
  1. The toLowerCase string is converted toLowerCase
  2. The toUpperCase string is converted toUpperCase
  3. The startswith method checks if the string begins with a specified substring, within the specified range if the arguments have the specified values beg and end.
str = "this is string example.... wow!!!";
print str.startswith( 'this' ); // true
print str.startswith( 'is'.2.4 ); // true
print str.startswith( 'this'.2.4 ); // false
Copy the code
  1. Trim Trim before and after whitespace trimLeft & trimRight same meaning

  2. NoSuchMethod is called when using a method that does not exist

A List of commonly used API

Website address: api.dartlang.org/stable/2.5….

Prepare a List first, and then perform all operations on the List

const List<Map<String.dynamic>> students = [
  { 'name': 'tom'.'age': 16 },
  { 'name': 'jack'.'age': 18 },
  { 'name': 'lucy'.'age': 20}];List numbers = [2.8.5.1.7.3];
Copy the code
  1. ForEach traverses a list or map
students.forEach((student) => print(student));
// {name: tom, age: 16}
// {name: jack, age: 18}
// {name: lucy, age: 20}
Map tom = { 'name': 'tom'.'age': 16 };
tom.forEach((key, value) => print(key + The '-' + value.toString()));
// name - tom
// age - 16
Copy the code
  1. A map can be used to manipulate each item in a given array and return a new array
var messages = students.map((student) => 'Hello ' + student['name']).toList();
print(messages);
// [Hello tom, Hello jack, Hello lucy]
Copy the code
  1. Contains () is used to determine whether an array contains an element
print(numbers.contains(5));
// true
Copy the code
  1. Sort () is used for sorting
numbers.sort((num1, num2) => num1 - num2);
print(numbers);
// [1, 2, 3, 5, 7, 8]
Copy the code
  1. reduce(), fold()
  • Reduce () adds each value in the array to the previously returned value and returns the sum of the sums
  • Fold () is used in much the same way as reduce(), except that it provides an initial value
  • Or JavaScript reduce is powerful,hahahhaha~
var sum = numbers.reduce((curr, next) => curr + next);
print(sum);
/ / 26

var sum2 = numbers.fold(10, (curr, next) => curr + next);
print(sum2);
/ / 36
Copy the code
  1. Every () is used to determine whether each item in the array meets a condition
var isAgeOver20 = students.every((student) => student["age"] > 20);
print(isAgeOver20);
// false

var isAgeOver15 = students.every((student) => student["age"] > 15);
print(isAgeOver15);
// true
Copy the code
  1. where(), firstWhere(), singleWhere()
  • Where () returns the set of elements in the array that meet the given criteria
  • FirstWhere () returns the first element in the array that satisfies the given condition
  • SingleWhere () returns the only element in the array that meets the given condition and throws an exception if there are more than one element that meets the condition
var ageOver16 = students.where((student) => student["age"] > 16);
print(ageOver16.toList());
// [{name: jack, age: 18}, {name: lucy, age: 20}]

var ageFirstOver16 = students.firstWhere((student) => student["age"] > 16, orElse: () => null);
print(ageFirstOver16);
// {name: jack, age: 18}

var ageUnder20 = students.singleWhere((student) => student["age"] < 16, orElse: () => null);
print(ageUnder20);
// null
Copy the code
  1. take(), skip()
  • Take (n) takes n elements from the array
  • Skip (n) skips n elements in the array
List arr = [1.3.5.2.7.9];

print(arr.take(3).toList());
/ / [1, 3, 5]
print(arr.skip(4).toList());
/ / [7, 9]
print(arr.take(3).skip(2).take(1).toList());
/ / [5]
Copy the code
  1. List.from() clones an array
List arr = [1.3.5.2.7.9];
var clonedArr = List.from(arr);
print(clonedArr);
// [1, 3, 5, 2, 7, 9]
Copy the code
  1. Expand () expand list (similar to js flat)
var arr1 = [[2.5], [7], [11.12]].var flattened = arr1.expand((item) => item).toList();
print(flattened);
// [2, 5, 7, 11, 12]

var arr2 = [2.5.8];
var computed = arr2.expand((item) => [item * 8]).toList();
print(computed);
/ / [16, 40, 64]

// Similar to map() when each item is evaluated
var computed2 = arr2.map((item) => item * 8).toList();
print(computed2);
/ / [16, 40, 64]
Copy the code
  1. add(), addAll()
  • Add () adds an element to the array
  • AddAll () adds all the elements of another array to the array
var arr1 = [1.3.5.9.2.1];
arr1.add(10);
print(arr1);
// [1, 3, 5, 9, 2, 1, 10]
arr1.addAll([15.21]);
print(arr1);
// [1, 3, 5, 9, 2, 1, 10, 15, 21]
Copy the code
  1. Clear () clears the array
numbers.clear(); / / []
Copy the code

The Map commonly used API

Website address: api.dartlang.org/stable/2.5….

Prepare a map and manipulate it later

const Map<dynamic.String>map = {'first': 'dart'.2: 'JavaScript'};
Copy the code
  1. The map assignment
Map<String.dynamic> letterMap = new Map(a); letterMap["a"] = "A";
letterMap["b"] = "B";
letterMap["c"] = "C";

print(letterMap); //{a:A, b: B, c: C}
Copy the code
  1. .isempty () isEmpty and.isnotempty () is non-empty
print(map.isEmpty()); //false
print(map.isNotEmpty()); //true
Copy the code
  1. . Keys and. Values Obtain the map key or value
print(map.keys); //(first,2)
print(map.values); //(dart,JavaScript)
Copy the code
  1. ContainsKey () and containsValue() Specifies a key and value
print(map.containsKey('first')); //true
print(map.containsValue('PHP')); //false    
Copy the code
  1. Remove (),removeWhere() specifies whether to delete by key name or by condition
map.remove('first');
print(map); // {2:'JavaScript'}
 map.removeWhere((key, value) => key is String);
 print(map); // {2:'JavaScript'}
Copy the code
  1. Several ways to traverse a map
// iterate over all keys
for (String key in map.keys) {
  print('$key');
}

// Iterate over all values
for (String value in map.values) {
  print('$value');
}

// Iterate over all key-values
map.forEach((key, value) => print('$key= =$value'));
Copy the code
  1. AddAll adds additional key-value pairs to the map
map.addAll({3:"PHP".4: "JAVA" });
Copy the code
  1. update(), updateAll()

update

  • If the specified key is found in the map, the value of the key is modified according to the rule specified by the second parameter
  • If the specified key is not found, the third parameter is checked to see if it is set
  • If the third parameter is set, elements are added to the current map after execution
// There is a key that needs to be changed
  var maps = {'one':'10'.'tow':20.'three': 30};
  maps.update('one',(value) {
    return '999';
  });
  print(maps);// {one: 999, tow: 20, three: 30}

// There is no key to change but a third parameter is specified
  maps.update('four',(value) {
    return '999';
  },ifAbsent: () => '123');
   print(maps);// {one: 10, tow: 20, three: 30, four: 123}
Copy the code

updateAll

  var maps = {'one':10.'tow':20.'three': 30};
  maps.updateAll((key, value) {
    return value+1;
  });
  print(maps); //{one: 11, tow: 21, three: 31}
Copy the code

Set common methods

Website address: api.dartlang.org/stable/2.5….

  1. Sets do not support literals. They can only be created using the set constructor and cannot have duplicate values
var Set set = new Set(a);set.add('a');
set.addAll(['b'.'c']);
print(set); // {a,b,c}
Copy the code
  1. difference(), intersection(), union()
  • Difference: specifies the difference set of two sets
  • Intersection Evaluates the intersection of two sets
  • Union merges sets and deduplicates them
/ / difference set
const List<int> list1 = [1.2.3.4];
const List<int> list2 = [2.3];
Set set1 = list1.toSet();
Set set2 = list2.toSet();
print(set1.difference(set2));/ / {1, 4}
/ / intersection
const List<int> list1 = [1.2.3.4];
const List<int> list2 = [2.3];
Set set1 = list1.toSet();
Set set2 = list2.toSet();
print(set1.intersection(set2));/ / {1, 4}
// merge de-weight
const List<int> list1 = [1.2.3.4];
const List<int> list23 = [2.3.5];
Set set1 = list1.toSet();
Set set2 = list23.toSet();
print(set1.union(set2)); // {1, 2, 3, 4, 5}
Copy the code
  1. RemoveAll (), removeWhere() delete by value and delete by condition
  • RemoveAll Deletes by value
  • RemoveWhere Delete by condition
const List<int> list1 = [1.2.3.4];
Set set1 = list1.toSet();
set1.removeAll( { 2.3});print(set1); / / {1, 4}
Set set2 = list1.toSet();
set2.removeWhere((value) => value > 1);
print(set2); / / {1}
Copy the code

The Dart Class

Classes and objects

1. What are classes in Dart

  • Declare a class using the keyword class
  • Create an object with the keyword new, which can be omitted (recommended)
  • All objects inherit from the Object class
void main() {
  Persion person = new Persion();
  Persion person1 = Persion(); // Do not use the new keyword
}

class Person {}Copy the code

2. Properties and methods in a class

  • Property generates getter and setter methods by default
  • Properties declared with final can only have getter methods
  • Properties and methods can only pass. access
  • Methods cannot be overloaded
void main() {
  Person person = Person();
  person.name = "yuanchen";
  person.age = 18;
  // Access properties
  print(person.name);
  // Access methods
  person.work();
}

class Person {
  String name;
  int age;
  final  String address = ' '; // The instance can only be accessed and cannot be changed
  void work() {
    print("Name is $name, Age is $age, He is Working"); }}Copy the code

Visibility of classes and members

  1. Visibility in Dart is measured in libraries
  2. By default. Each Dart file is a library
  3. Use underscores (_) to indicate privacy
  4. Import the library using import
//a.dart
import 'b.dart';
void main() {
  Person person = Person();
   person.name = "yuanchen";
   person.age = 18;
   print(person.name);
}
//b.dart
class Person{ // If Person is underlined (_), the Person class will not be accessible in a.art, only in the current file (b.Art)
  String name;
  int age;
  void work() {
    print("Name is $name, Age is $age, He is Working"); }}Copy the code

Calculate attribute

  1. The value of the computed property is computed and does not store the value itself
  2. Evaluate property assignments and convert to other instance variables by evaluating them
  3. A calculated property is the property of the current class, and a method is intended to express some behavior of the class
void main() {
  Rectangle rectangle = Rectangle();
  rectangle.width = 20;
  rectangle.height = 10;
  print(rectangle.area);
  / / use the setter
  rectangle.area = 200;
  print(rectangle.width);
}

class Rectangle {
  num width, height;
  // Return the area through the getter
  num get area {
    return width * height;
  }
  // Set the width by setter
  set area(value) {
    width = value / 20; }}Copy the code

A constructor

  1. If no constructor is explicitly defined, there is a default constructor
  2. If a custom constructor exists, the default constructor is invalid
void main() {
  Person person = Person('yuanchen'.20);
  print('${person.name}-- ${person.age}');
}

class Person {
  String name;
  int age;
  final  String gender = ' ';

  Dart creates such a constructor by default if not written
// Person() {}

  Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  void work() {
    print("Working"); }}Copy the code
  1. Constructor syntax sugar
void main() {
  Person person = Person('yuanchen'.20);
  print('${person.name}-- ${person.age}');
}

class Person {
  String name;
  int age;
  // Constructor syntax sugar
  Person(this.name, this.age);
  / / equivalent to the
// Person(String name, int age) {
// this.name = name;
// this.age = Element.age;
/ /}
}
Copy the code
  1. Variables defined through final can only be initialized in the form of syntactic sugar or initializer list (described below), because both initializer properties are initialized before the constructor executes
void main() {
  Person person = Person('yuanchen'.20.'male');
  print('${person.name}-- ${person.age}');
}

class Person {
  String name;
  int age;
  final String gender; // Final variables can only be initialized using syntactic sugar or initializer lists
  // Constructor syntax sugar
  Person(this.name, this.age,this.gender);
}
Copy the code
  1. Constructors cannot be overloaded, but there are named constructors
// Multiple constructors can be implemented using named constructors
// Use the class name. The formal implementation of a method
void main() {
  Person person = Person('yuanchen'.20.'male');
  print('${person.name}-- ${person.age}');
  // Instantiate the named constructor
  Person person1 = Person.withName('male');
  print(person1.gender);
}

class Person {
  String name;
  int age;
  final String gender;
  // Constructor syntax sugar
  Person(this.name, this.age,this.gender);
  // Name the constructor
  Person.withName(this.gender);
}
Copy the code
  1. The constructor parameter is optional
void main() {
  // We can instantiate without initializing the age property and run with the given default value
  Person person = Person('yuanchen');
  print('${person.name}-- ${person.age}');
  // If passed, the given default value will be overridden
  Person person1 = Person('yuanchen',age: 21);
  print('${person1.name}-- ${person1.age}'); // Print yuanchen-- 21
}

class Person {
  String name;
  int age;
  // Constructor syntax sugar
  Person(this.name, {this.age = 20});
}
Copy the code

Constant construction method

  1. If the class is immutable, you can define the object as a compile-time constant
  2. To declare a constructor using const, all properties of the current class must be final
  3. Declare an object using const, which can be omitted
  4. For scenarios such as properties that are assigned only once, you can use the constant constructor because constants are faster at run time and are determined at compile time
void main() {
  const person = const Person('yuanchen'.20);
  print(person.name);
}

class Person {
  final String name;
  final int age;
  const Person(this.name, this.age);
}
Copy the code

Plant construction method

  1. The constructor is preceded by factory to implement a factory method
  2. Objects can be returned in the factory constructor
  3. Using scenarios is the manual serialization of Json in flutter
// The official website example implements the cache effect
class Logger {
  final String name;
  static final Map<String, Logger> _catch = <String, Logger> {};
  factory Logger(String name) {
    if(_catch.containsKey(name)){
      // The factory constructor can return objects
      return _catch[name];
    }else {
      final logger = Logger._internal(name);
      _catch[name] = logger;
      // The factory constructor can return objects
      return logger;
    }
  }
  Logger._internal(this.name);
  void log(String msg) {
    print(msg); }}Copy the code

Initialization list

1. Initializing lists is executed before constructors 2. Initializing lists using commas 3. Initializer lists are usually used to set the value of final variables

void main() {
  Person person =  Person({'name':'yuanchen'.'age': 20.'gender':'male'});
  print(person.gender);
}

class Person {
   String name;
   int age;
   final String gender;
   // Initializer lists can also be assigned to non-final attributes
   Person(Map map): gender = map['gender'], name = map['name'] {this.age = map['age']; }}Copy the code

Static members

  1. Use the static keyword to declare class-level properties or functions
  2. Static members cannot access non-static members, and non-static members can access static members
  3. Class constants need to be declared using the static const class
void main() {
  Page page = Page();
  // Static methods belong to the current class, not the instance, and can only be called from the current class
  Page.scrollDown();
}
class Page {
  // Class constants are declared static
  static const int maxPage = 10;
  static int currentPage = 1;
  static void scrollDown() {
    currentPage = 1;
    print('scrollDown.... ');
  }

  void scrollUp() {
    // The scrollUp() method is non-static so non-static members can access static members
    currentPage++;
    print('scrollUp.... '); }}Copy the code

Object operator

  1. Cascade operators (..)
  2. The AS operator forces a variable type change
void main() {
  Person person =  Person();
  // Cascade operatorperson.. name ='yuanchen'
        ..age = 20;

  // as operator
  var person1;
  Person1 is not assigned, but is cast to Person by AS to call an attribute or method in the class
  // But the current case is an error because the name attribute is null even though it is of type Person
  (person as Person).name = 'zs';
}

class Person {
   String name;
   int age;
}

Copy the code

Object Call method

  1. If the class implements the call() method, then the object of the current class can be used as a method (not recommended)
void main() {
  Person person =  Person('yuanchen'.20);
  // Use the object as a method
  person('zs'.30);
}

class Person {
   String name;
   int age;
   Person(this.name,this.age);
   // Implement call method name must be call
   Map call(String name, int age) {
      print('Name is $name, Age is $age, He is working');
      // Returns a value
      return {'name':name,'age':age}; }}Copy the code

inheritance

  1. Extends a class using the extends keyword
  2. Subclasses inherit properties and methods visible to their parent class, not constructors
  3. Subclasses can override methods of their parent class, getter setters
  4. Single inheritance, polymorphism
  5. All classes inherit from Object by default because there is a toString method by default
// Person.dart 
class  Person {
  String name;
  int age;
  String _birthday;
  bool get isAdult => age > 18;
  void run() {
    print('Person is running... '); }}//Student.dart
import 'Person.dart';
void main() {
  Student student = new Student();
  student.study(); //Student study....
  student.name = 'yuanchen';
  student.age = 16;
  / / student. _birthday = '4.29'; Private attributes of the parent class cannot be used
  student.run(); // Override the parent class method to print Student is running...
  print(student.isAdult); // Overrides the parent class to print true

  / / a polymorphism
  // The subclass's implementation is assigned to the parent class's reference, so the person instance can only call the person methods and properties
  Person person = new Student();
  person.age = 16;
  print(person.isAdult);// true Returns true because this is the parent type but the subclass implementation is used
}

// Extends Person via extends
class Student extends Person{
  void study() {
    print('Student study.... ');
  }
  // Overrides the computed properties of the parent class
  bool get isAdult => age > 15;

  // Override the parent class method
  void run() {
    print('Student is running ... '); }}Copy the code

Constructor in inheritance

  1. By default, the constructor of a subclass calls the nameless, no-argument constructor of its parent class
void main() {
  Student student = Student(); // Prints Person...
}

class Person {
  String name;
  Person() {
    print('Person.... '); }}class Student extends Person {
  int age;
}
Copy the code
  1. If the parent class has no nameless, parameterless constructor, you need to call the parent constructor explicitly
  2. A colon (:) is used after the constructor argument to indicate that the parent class constructor was called
void main() {
  Student student = Student('yuanchen');
  print(student.name);
}

class Person {
  String name;
  Person(this.name);
  Person.withName(this.name);
}
class Student extends Person {
  int age;
  // If there is no nameless constructor in the parent class, the constructor is required to display
    Student(String name) : super(name);
  You can also explicitly call the superclass named constructor if there is one in the parent class
  //Student(String name): super.withName(name);
}
Copy the code
  1. The constructor of the parent class is called before the subclass constructor body begins execution
  2. If there is an initializer, the initializer is executed before the parent constructor
void main() {
  Student student = Student('yuanchen'.'male');
  print(student.name);
}

class Person {
  String name;
  Person(this.name);
  Person.withName(this.name);
}
class Student extends Person {
  int age;
  final String gender;
  // Gender of the initialization list is called before super of the parent class
  Student(String name, String gender) : gender  = gender ,super(name);
}
Copy the code

An abstract class

  1. Abstract classes are represented by abstract and cannot be instantiated directly
  2. Abstract classes can have no abstract methods
 abstract class Person {
  // An abstract class can have no abstract methods
  // There is an empty implementation with no abstract methods
  void run(){}
}
Copy the code
  1. Abstract methods need no abstract modifier and have no implementation
 abstract class Person {
  void run();
}
Copy the code
  1. Classes with abstract methods must be declared as abstract classes
  2. Implementing abstract classes
void main() {
  Person person = new Student(); / / polymorphism
  person.run();
}
 abstract class Person {
  void run();
}

class Student extends Person {
  void run() {
    print('Inherit abstract classes to implement abstract methods'); }}Copy the code
  1. Abstract classes in DART are more like interfaces in other languages

interface

  1. Classes and interfaces are unified; classes are interfaces (which is weird)
  2. Each class implicitly defines an interface containing all instance members
  3. If you reuse an implementation of an existing class, use inheritance (extends)
  4. Implements an interface (implements) if you are using an existing class behavior
void main() {
  Student student = new Student();
  print(student.age); / / 10
}
class Person {
  String name;
  int get age => 18;
  void run() {
    print('person run ... '); }}class Student implements Person{
  @override
  String name;

  @override
  // TODO: implement age
  int get age => 10;

  @override
  void run() {
    // TODO: implement run}}Copy the code
  1. It is better to use an abstract class as an interface, which is more like an interface. The above form (a class is an interface) is strange
void main() {
  Student student = new Student();
  student.run(); / / 10
}
 abstract class Person {
  void run();
}

class Student implements Person{

  @override
  void run() {
    print('Student is running .... '); }}Copy the code

Mixins

  1. Mixins use with to connect one or more minxins, similar to multiple inheritance, which is a way of reusing a class’s code in multiple inheritance
void main() {
  D d = new D();
  d.a(); //A.a()....
  d.b(); // B.b()....
  d.c(); // C.c()....
}

class A {
  void a() {
    print("A.a()...."); }}class B {
  void b() {
    print("B.b()...."); }}class C {
  void c() {
    print("C.c()...."); }}// Inherit ABC classes
class D extends A with B.C{}Copy the code
  1. Classes that are mixins cannot have explicitly declared constructors
void main() {
  D d = new D();
  d.a(); //A.a()....
  d.b(); // B.b()....
}

class A {
  void a() {
    print("A.a()...."); }}class B {
  // cannot have a display constructor as a Mixin
// B() {}
  void b() {
    print("B.b()...."); }}// Inherit ABC classes
class D extends A with B{}Copy the code
  1. A class that is a Mixin can only inherit from Object and no other inheritance

4. Mixins can realize both multiple inheritance and assembly. They can assemble multiple classes with different functions into a final class

abstract class Engine {
  void work();
}
class OilEngine implements Engine {
  @override
  void work() {
    print('Work with oil'); }}class ElectricEngine implements Engine {
  @override
  void work() {
    print('Work with Electric'); }}class Tyre {
  String name;
  void run() {}
}

// An electric car
class Car = Tyre with ElectricEngine; // A car that uses oilclass Bus = Tyre with OilEngine; // There are two different ways to implement the behavior of the current classclass Car1 extends Tyre with ElectricEngine {
  String color;
}

Copy the code
  1. I feel that this is a strong batch of things that can put different business modules together

Overwrites the operator

  1. The override operator needs to be defined in the class
// The format of the overwrite operator
// Return value operator The symbol to overwrite (argument list) {
  / / the method body
/ /}

void main() {
  Person person1 = Person(18);
  Person person2 = Person(20);
  // Objects have no greater than symbol (>) but can be compared by overriding the greater than symbol
  print(person1 > person2); //false

  // Objects access properties or methods using the dot (.). If you want to access ['age'], you can override the operator
  print(person1['age']);
}

class Person {
  int age;

  Person(this.age);

  bool operator >(Person person) {
    return this.age > person.age;
  }

  int operator[] (String str) {
    if ("age" == str) {
      return age;
    }
    return 0; }}Copy the code