1 Declare variables and constants

1.2 withvarDeclare a variable

void main() {
  var foo = 'string';
  var bar = 0;
  var arr = ['e1'.'e2'];
  print(foo);
  print(bar);
  print(arr); '> Enter:' 'bash string0
[e1, e2]
ga
Copy the code
void main() {
  var foo; 
  foo = 0;
  foo = "string";
  foo = [];
  print(foo);
}
Copy the code

The output is:

[]
Copy the code

1.2 Declare variables with specified types

void main() {
  String str;
  int num;
  bool boo;
  var identifier = new Map(a); }Copy the code

1.3 finalUse of keywords

Final is also used for declarations, but only once. And can no longer be assigned.

void main() {
  final foo = 1;
  foo = 2; // <-- cannot be assigned again
  print(foo);
}
Copy the code

Although final can only be declared once, in the case of compound types, its child elements can be modified without being banned, as long as the compound type remains unchanged.

void main() {
  final bar = new Map(a); bar["index"] = 1;  // <-- If a compound variable is declared, operations on child elements are not prohibited
  bar["index"] = "I'm a string";  // <-- you can do whatever you want with the child elements
  print(bar);
}
Copy the code

1.4 Declaring Constants

Constant declarations can only declare values of a single type.

void main() {
  const num = 1;
  const str  = "hello world";
  const b = true;
}
Copy the code

Built-in data types and operators

Dart provides seven data types in total:

  • Num (int/double) Indicates the numeric type
  • String String type
  • Bool Indicates the Boolean type
  • List List type
  • Map Mapping type
  • Symbol type
  • Runes

2.1 Number type

void main() {
  num foo = 1; // Declare a number, either an integer or a floating-point number
  int bar = - 1;  // Declare an integer
  double baz = 0.1; // Declare a floating point number
  print(foo.runtimeType); // Prints an int
  foo = 0.1;
  print(foo.runtimeType); Num can be converted between int and double
}
Copy the code

2.1.1 Operation of Number type

The dart operators are: +, -, *, /, ~/, %, etc. ~/ is the dart specific integer operator

void main() {
  num foo = 1; // Declare a number, either an integer or a floating-point number
  int bar = - 1;  // Declare an integer
  double baz = 0.1; // Declare a floating point number
  print(foo.runtimeType); // Prints an int
  foo = 0.1;
  print(foo.runtimeType); Num can be converted between an int and a double
}
Copy the code

Some common built-in methods of type 2.1.2 Number

void main() {
  num foo = 2.1;
  print(foo.round()); // Round off
  print(foo.ceil()); // take the round
  print(foo.floor()); // take the integer
  print(foo.abs()); / / the absolute value
}
Copy the code

2.2 String Types

2.2.1 String declaration

  String foo = "hello world"; // <-- single line declaration with double quotation marks
  foo = 'hello world'; // <-- single quotes
  foo = ''' line1 line2 ... ' ' '; // <-- multiple lines, similar to formatting strings
Copy the code

2.2.2 String operators

String foo = "hello world";
print(foo + "!"); / / < - joining together
print(foo * 2); // <-- concatenate itself twice
print(foo == foo); // < string comparison
print(foo[0]); // <-- take the character with subscript 0
Copy the code

The output

hello world!
hello worldhello world
true
h
Copy the code

2.2.3 String interpolation expressions

String dart = 'dart';
print("hello, ${dart}"); // <-- open hello,dart
Copy the code

2.2.4 Common Attributes of Strings

String dart = 'dart';
print(dart.length); // Length: 4
print(dart.isEmpty); // 是否为空: false
print(dart.isNotEmpty); // Is not null: true
Copy the code

2.2.5 Common Methods

String dart = ' dart ';
print(dart.contains('dart')); // Whether dart is included
print(dart.toLowerCase()); // Convert to lowercase
print(dart.trim()); / / to space
print(dart.trimLeft()); // go to the left space
print(dart.trimRight()); // go to the right space
print(dart.indexOf('d')); // Where d is located
print(dart.lastIndexOf('a')); // The reciprocal position of a
print(dart.split('r')); // Split r into lists
print(dart.endsWith(' ')); // The last character is a space
print(dart.startsWith(' ')); // The first character is a space

Copy the code

2.3 Boolean value

bool isOk = true;
print(isOk);
Copy the code

2.4 the List array

Against 2.4.1 statement

var foo = [1.2.3."hello world"];
print(foo[0]); <-- prints 1
foo[0] = "hello world";
print(foo[0]); // <-- prints hello world
var bar = const[1.2.3]; // <-- declare that the list cannot be changed
var [0] = 1; // <-- error: unchangeable
var baz = <String> [];// Generics specify the type of the element
Copy the code

2.4.2 Common Attributes and Methods

var foo = [1.2.3."hello world"];
print(foo[0]); <-- prints 1
foo[0] = "hello world";
print(foo[0]); // <-- prints hello world
var bar = const[1.2.3]; // <-- declare that the list cannot be changed
var [0] = 1; // <-- error: unchangeable
Copy the code

2.5 the Map type

2.5.1 statement

var foo = {"foo": 1."bar": "hello world"."baz": true}; // <-- declare map
print(foo); // <-- {foo: 1, bar: hello world, baz: true}
foo["newItem"] = "hello";
print(foo); // <-- {foo: 1, bar: hello world, baz: true, newItem: hello}
var bar = const {"foo": 1}; // <-- declare immutable map variables cannot be changed after the declaration
bar["foo"] = 2; // Error, cannot be modified
var baz = <num.String> {};// <-- specifies the type
baz[1] = "str";

Copy the code

2.5.2 Common Attributes and Methods

var foo = {"foo": 1."bar": "hello world"."baz": true};
print(foo.length); // <-- length attribute 3
print(foo.keys); {foo, bar, baz}
print(foo.values); <-- list of all keys {1, hello world, true}

print(foo.containsKey("foo")); // <-- contains the foo key true
print(foo.containsValue(1)); // <-- contains the 1 key true

foo.forEach((k, v) {
print("key = ${k}, value = ${v}"); // <-- prints the key name and value
});
Copy the code

2.6 Dynamic Indicates the dynamic type

2.6.1 statement

var foo; // <-- var is declared and values are not initialized. The default type is dinamic dynamic
foo = 1;     // Can be assigned to int again
foo = "str";// Can be assigned to string again
foo = true;// We can assign bool again
foo = [];  // Array and so on
print(foo);

dynamic bar; // <-- declared with the dynimac keyword
bar = 1;
bar = "str";
bar = true;
print(bar);
Copy the code

3 operators

3.1 Addition, subtraction, multiplication and division operators

The operator instructions The sample
+ add print(1 + 1), output: 2
- Reduction of print(2 - 1), output: 1
* take print(2 * 1), output: 2
/ In addition to print(2 / 2), output: 1
~ / In addition to integer print(3 ~/ 2), output: 1
% In addition to more than print(5 % 2), output: 1

3.2 Increment decrement operator

var foo = 3;
print(foo++); // <-- incrementing: 3
print(foo); // <-- result: 4
print(++foo); // <-- increment before execution: 5

print(foo--); < span style = "box-sizing: border-box
print(++foo); < span style = "box-sizing: border-box
Copy the code

3.3 Relational operators

The operator instructions The sample
= = Equal to the judge print(true == true); Output: true,
! = Before judging print("foo" ! = "bar");Output: true,
> Is greater than print( 1 > 2); Output: false
< Less than print( 1 < 2); Output: true,
> = Greater than or equal to print( 1 >= 2); Output: false
< = Less than or equal to print( 1 <= 2); Output: true,

3.4 Logical operators

The operator instructions The sample
! non print(! false); Output: true,
&& with print(true && true); Output: true,
` ` or

3.5 Assignment operators

The operator instructions The sample
= The assignment var foo = 1;
?? = The compound operator, given by??and=If it is null, the value is assigned; if it is not null, the value is not assigned var bar; bar ?? = 1;Bar has no initialization value, then 1 is assigned, and vice versa is not processed
+ = And etc. int foo = 0; foo += 1;
- = Reduction etc. int foo = 0; foo -= 1;
* = Take etc. int foo = 0; foo *= 2;
/ = In addition to etc. int foo = 4; foo /= 2;
~ / = In addition to integer, etc int foo = 5; foo ~/= 3;
% = Take more than the whole, etc int foo = 5; foo %= 3;

3.6 bit operator

3.6.1 Bitwise and (&)

// bit with (&)
final value = 0x22; / / 100010
final bitmask = 0x0f; / / 001111
/ / 100010
/ / & 001111
// --------
/ / 000010
print(value & bitmask ); // Print 2
Copy the code

3.6.2 bitwise or (|)

/ / bitwise or (|)
final value = 0x22; / / 100010
final bitmask = 0x0f; / / 001111
/ / 100010
/ / | 001111
// --------
/ / 101111
print((value | bitmask )); // Prints 47
Copy the code

3.6.3 Bitwise Non-(~)

// Bit non-(~)
final value = 9; // 01001 is signed
// 0 1 0 0 1 +9 The highest bit of binary 0 integer 1 negative
// 0 0 1 1 0 complement
// 1, 1, 0, 0, 1
// 1 1 0 1 0 + 1
// --------
// 1 10 1 0-10
print( value.toRadixString(2));/ / 1001
print( (~value).toRadixString(2));/ / - 1010
Copy the code

3.6.4 radar echoes captured xor (^)

// if (^) is different, it is 1
var foo = int.parse("1010", radix: 2);
var bar = int.parse("0010", radix: 2);
// 10 10 10
// 0 0 1 0 2
// --------
// 1 0 0 0 8
print(foo ^ bar); / / 8
Copy the code

3.6.5 moves to the right (> >)

/ / moves to the right (> >)
var foo = int.parse("0010", radix: 2);
// the binary number of 0010 2
// 0001 moves right 1 bit
print(foo >> 1);
Copy the code

3.6.6 left (< <)

/ / moves to the right (< <)
var foo = int.parse("0010", radix: 2);
// the binary number of 0010 2
// 1000 moves 2 bits 1 to the left
print(foo << 2); / / 8
Copy the code

3.7 Conditional Expressions

3.7.1 Ternary expressionscondition ? expr1: expr2

var isOk = true;
String res = isOk ? "i'm Ok" : "It's bad";
print(res);
Copy the code

4 Process Control

Basically consistent with the C language style

4.1 ifConditional statements

bool conditionA = true;
bool conditionB = true;
if (conditionA) {
    // do something
} else if (conditionB) {
    // do something
} else {
    // do something
}
Copy the code

4.2 forfor... in...cycle

var items = [1.2.3.4.5];
for (var i = 0; i < items.length; i++ ) {
    print(items[i]);
}
for (var item in items) {
    print(item);
}
Copy the code

4.3 whilecycle

  int mux = 0;
  while (mux < 5)  {
    print(mux);
    mux++;
  }
  print("--${mux}-- -- -- -- -- -");
  do {
    print(mux);
    mux--;
  } while(mux > 0);
Copy the code

4.4 Loop Keywordsbreakandcontinue

  var continueItem = 2;
  var breakItem = 3;
  var items = [1, continueItem, breakItem ];

  for (var item in items) {
    if (item == breakItem) {
      print("break\n");
      break;
    }
    print(item);
  }
  print("----Dividing Line-----");
  for (var item in items) {
    if (item == continueItem) {
      print("continue\n");
      continue;
    }
    print(item);
  }
Copy the code

The output

1
2
break

----Dividing Line-----
1
continue

3
Copy the code

4.5 switch... caseprocess

Unlike the C-style switch, Dart adds a continue jump tag on top of this as follows:

switch(<condition>) {
    case <case1>:  
        // todo ...
    continueTag; < tag > case2 < tag >case <case2>: 
        // todo ...
    break;
    default: 
        // todo ...
}

Copy the code
var getYouColorToSeeSee = 'black';
switch(getYouColorToSeeSee) {
case 'black':
  print("Oh, It's black");
  continue anotherColor;
anotherColor:
case 'white':
  print("Oh, It's white");
  break;
default:
  print('I can\'t see anything');
}
Copy the code

The output

Oh, It's black
Oh, It's white
Copy the code

Five methods

5.1 Definition of methods

The definition paradigm of the method is:

typeFunctionName (arg1, arg2,...). { // todo ...return result
}
Copy the code
String AreYouOk (String name) {
    return "${name}: Are you ok?";
}
String AreYouOkAlias (String name) => "${name}: Are you ok?"; // <-- if you can do it with one line, you can do it with arrows
print(AreYouOk("Lei jun"));
Copy the code

The output

Lei Jun: Are you ok?Copy the code

5.2 Optional Parameters

When a method is called, some parameters can be passed and some parameters can not be passed. These are viable parameters.

5.2.1 Naming This parameter is optional

Optional arguments You can specify which optional arguments to pass by naming them, for example:

String Foo (String arg, {String option1 = "".int option2 = 0{})return "arg=>${arg}, option1 => ${option1}, option2 => ${option2}";
}

print(Foo("hello", option1: "hello"));
Copy the code

The output

arg=>hello, option1 => hello, option2 => 0
Copy the code
5.2.2 Naming This parameter is optional
String Foo (String arg, [String option1 = "".int option2 = 0]) {return "arg=>${arg}, option1 => ${option1}, option2 => ${option2}";
}

print(Foo("hello"."hello"));
Copy the code

The output

arg=>hello, option1 => hello, option2 => 0
Copy the code

Naming optional parameters is much more readable

5.3 the closure

  • A closure is a method object
  • Closures are defined inside other methods
  • Closures can access local variables of external methods and hold their state, which is the main use of closures
Function foo () {
    var total = 0;
    return() = > {print(++total)
    };
};

var fooIns = foo();
fooIns();
fooIns();
fooIns();
Copy the code

The output

1
2
3
Copy the code

You can see that as the fooIns are called several times, the state inside remains the same as the last operation. This means that a closure can remain unchanged from the last execution without exposing variables. A closure retains its state because the declared variable inside it is accessed again by an anonymous method. As in the example above, the variable total was declared when foo was called. The variable total should be destroyed when foo completes execution, but since it is accessed in the next anonymous method, That is, the variable is accessed on the next stack (anonymous method), so the variable total cannot be destroyed to ensure that the next stack can access it, which is why the closure has its state.

6 Object Oriented

6.1 Declaring Objects and Properties

void main() {
  var personIns = Person();
  personIns.name = "foo";
  personIns.age = 18;
  personIns.introduce();
}

class Person {
  String name = "";
  int age = 0;

  void introduce() {
    print("Name is ${name}, age is The ${this.age}"); }}Copy the code

The output

Name is foo, age is 18
Copy the code

Unlike other languages, Dart can be instantiated with the new keyword or omitted.

6.2 Library visibility and class visibility

In DART, a file is a library, and in this file, if the definition name begins with an underscore, the variable cannot be exported. Create a new file called util.dart with the following contents:

class _bar {}// No exposure to the outside world
class person {
  String _name = ""; // <-- class member attributes are not exposed
  String name = ""; // <-- class attributes are exposed
  void _introduce() { } // Same principle
  void introduce() { }  // Same principle
}
String foo = ""; // External exposure
Copy the code

Dart library import util. Dart library and use

import 'util.dart'; // Import the library
void main() {
 print(foo); // Access normal
 print(_bar); // Not accessible
 personIns = person();
 print( personIns.name ); // Access normal
 print( personIns._name ); // The access failed
}
Copy the code

6.3 Calculating Attributes

A calculated property is computed and can be viewed as a method in itself, and the result returned is the property. Consistent with typescript’s concept of computed properties. Such as:

void main() {
  var feeIns = new Goods();
  print(feeIns.totalFee());
}

class Goods {
  num price = 10./ / price
      total = 10; / / the number of

 // Return the total cost
  num totalFee() {
    returnprice * total; }}Copy the code

In general, the cost is more like an attribute, can be directly obtained, so here to define a method to represent the action to obtain, feel very incompatible. Costs are calculated, so that’s where the calculated attributes come in. Modified as follows:

void main() {
  var feeIns = new Goods();
  print(feeIns.totalFee);
}

class Goods {
  num price = 10./ / price
      total = 10; / / the number of

 / / the total cost
  num get totalFee => price * total;
}
Copy the code

The same is true for setting calculation properties, such as:

void main() {
  var feeIns = new Goods();
  print(feeIns.totalFee);
  feeIns.totalFee = 70;
  print(feeIns.total);
}

class Goods {
  final num price = 10; // Here the price is fixed
  num total = 10; / / the number of

 // Calculate attributes to get the total cost
  num get totalFee => price * total;

  // Calculate the total cost of setting properties
  set totalFee(num newFee) {
    total = newFee / price; // Since the price is fixed, the quantity of the item needs to be changed to meet the current cost}}Copy the code

The output

100
7.0
Copy the code

6.4 Construction Method

Constructors are class name methods.

void main() {
  var goodsIns = Goods(10.10);
  print(goodsIns.totalFee);
}

class Goods {
  num price = 0;
  num total = 0;

  Goods(num price, num total) {
    this.price = price;
    this.total = total;
  }

 // Calculate attributes to get the total cost
  num get totalFee => price * total;

  // Calculate the total cost of setting properties
  set totalFee(numnewFee) { total = newFee / price; }}Copy the code

The output

100
Copy the code

If the passed argument is followed by a direct initialization of the class’s properties, then the syntax sugar in the argument can be assigned directly to the property using the this keyword.

.class Goods {
  num price;
  num total;

  Goods(this.price, this.total); // Syntax short form of sugar. }Copy the code

6.5 constant class

A class is a constant class if its properties can be set only once. Constant classes may perform faster than classes that assign values repeatedly. Properties of constant classes are defined with the final keyword, for example:

void main() {
  const goodsIns = Goods(10.10);
  print(goodsIns.getFee());
}

class Goods {
  final num price;
  final num total;
  const Goods(this.price, this.total);

  num getFee()  => price * total;
}
Copy the code

The output

100
Copy the code

6.6 Initializing the List

The initializer list can be used to initialize class parameters, which precede the default constructor and is itself a custom constructor.

void main() {
  var goodsIns = Goods.withMap({'total': 10});
  print(goodsIns.getFee());
}

class Goods {
  num price = 10;
  final num total;

  Goods.withMap(Map map): total = map['total'];

  num getFee()  => price * total;
}
Copy the code

The output

100
Copy the code

6.7 Static Members

  • Static member usagestaticKeywords are defined before variables and methods
  • Static members cannot access non-static members, while non-static members can access static members, because static members are resident in memory, while non-static members are not necessarily resident in memory. So we have static

Member whose non-static members have not been instantiated, and vice versa.

  • Class constants need to be usedstaticandconstTo declare
  • Instantiated classes cannot access static members
pvoid main() {
  SuperMan.fight(); // <-- call directly, no instantiation
}

class SuperMan {
  static void fight() {
    print("Ahh, ahh, ahh, ahh...");
    print("KO"); }}Copy the code

The output

Ah, beat, beat, beat... KOCopy the code

6.8 Object Operators

6.8.1 Object member predictor?

Applies to members of an object that are not sure whether they exist, if they are called, if not called. If you write if, you write thousands more, and you write? One line will do. This is the same thing as TS.

pvoid main() { SuperMan? .fight();// If it exists, use it
}

class SuperMan {
  static void fight() {
    print("Ahh, ahh, ahh, ahh...");
    print("KO"); }}Copy the code

6.8.2 asTypes of assertions

If a variable’s type is unknown, you can force an assertion on it with AS. Such as:

void main() {
  var man; // Do not give any type
  man = SuperMan();
// Man does not specify a specific type, so we cannot derive what the variable is
  (man as SuperMan).fight();
}

class SuperMan {
  void fight() {
    print("Ahh, ahh, ahh, ahh...");
    print("KO"); }}Copy the code

6.8.3 isand! isType judgment

Used to determine the type of a variable

void main() {
  var man; // Do not give any type
  man = SuperMan();
  if (man is SuperMan) { // < Supermanman.fight(); }}class SuperMan {
  void fight() {
    print("Ahh, ahh, ahh, ahh...");
    print("KO"); }}Copy the code

6.8.4 Cascade Operators.

When a member of the same object is continuously assigned or called, it serves as a shorthand for a type chain call.

void main() {
  varsuperMan = SuperMan(); superMan.. heroBar ="bar". heroFoo ="foo". fight(); }class SuperMan {
  String heroFoo = "";
  String heroBar = "";

  void fight() {
    print("${heroFoo} VS ${heroBar}"); }}Copy the code

The output

foo VS bar
Copy the code

6.9 callmethods

If a class implements a Call method, the object instantiated by that class can also be called once as a method. This is similar to closures, which can be called again with the result of one call.

void main() {
  var superMan = SuperMan();
  superMan(); <-- call the call method

}

class SuperMan {
  void call() {
    print("The competition is progressing..."); }}Copy the code

7 Advanced object-oriented features

Dart’s object-oriented inheritance, abstract classes, and interfaces are basically the same as Java’s, but, unlike other programming languages, are overridden by Mixins operators.

7.1 inheritance

As with Java, TS, and PHP, DART inherits its parent class with the extends keyword:

  • Subclasses inherit visible properties and methods from their parent class
  • Subclasses can define methods of members of the same name again to override inherited members of the parent class.
  • Single inheritance
void main() {
  Parent("foo".35).. ohAreYou() .. howOldAreYou(); Child("bar".5)
    ..ohAreYou() // <-- calls the parent method
    ..howOldAreYou(); // <-- override the parent method
}

class Parent {
  String name;
  int age = 0;

  Parent(String this.name, int this.age);

  void ohAreYou() {
    print("${name}, Your dad.");
  }

  void howOldAreYou() {
    print("${age}"); }}class Child extends Parent {
  Child(String name, int age) : super(name, age);

  @override
  void ohAreYou() {
    print("${name}, Your son."); }}Copy the code

The output

foo, Your dad.
35
bar, Your son.
5
Copy the code

7.1 Constructors in inheritance

If a subclass does not display a declared constructor and the parent class has a declared no-argument constructor, the parent class’s constructor is called by default when instantiated.

void main() {
  Parent();
  Child(); // <-- calls the parent constructor
}

class Parent {
  Parent() {
    print(this.toString()); }}class Child extends Parent {}Copy the code

However, if the parent constructor has parameters, the child class also explicitly implements the constructor and calls the parameters required by the parent constructor.

void main() {
  Parent("hello");
  Child(); // <-- calls the parent constructor
}

class Parent {
  Parent(String foo) {
    print(foo); }}class Child extends Parent {
  Child() : super("hello"); // <-- if the parent class has a constructor and parameters are required, the subclass displays the declaration and calls the parent constructor
}
Copy the code

The output

hello
hello
Copy the code

The constructor of the parent class starts execution at the point where the subclass constructor calls the parent constructor.

7.2 the abstract class

Abstract classes are the same as the abstract classes of Java, TS, and other object-oriented programming languages. Abstract classes can be regarded as a normal class, but the property constructor and method declaration of this class are declared in a descriptive way, and its purpose is to be inherited by the subclass must implement abstract methods. This means that once a subclass inherits from the abstract class, it must implement the abstract class description. Common usage scenarios for abstract classes include workshop pattern development. How to ensure that the application classes produced in the workshop are consistent, abstract class is a good constraint, as long as every class produced in the workshop pattern inherits from the same abstract class, then we can ensure that every output class has a consistent implementation. The declaration keyword of an abstract class is abstract, as in:

voidmain() { Altman() .. fight()Take / /
    ..fly(); / / take off
}

// Declare the Superman abstract class -- that is, the standard standard for superman
abstract class SuperManAbstract {
  / / to flying
  void fly () ;

  // Be able to fight
  void fight();
}

// Define ultraman Superman
class Altman extends SuperManAbstract {
  @override
  void fight() {
    print('Ultraman Laser... ');
  }

  @override
  void fly() {
    print('Ultraman flight mode... '); }}Copy the code

The output

Ultraman Laser... Ultraman flight mode...Copy the code

7.2 interface

The function of the interface is very similar to the abstract class, which is used to constrain the implementation of the class, so why there is an abstract class but also an interface class? This is because the interface is used to implement the key word is implements the abstract class is inheritance, in the dart is only single inheritance, such as implementing a kaka ronaldo’s turtler qigong and vegeta handsome super people, if using abstract classes, so kaka, ronaldo is an abstract class, and vegeta is an abstract class, Dart cannot have two classes at the same time. The answer is that multiple inheritance is not possible, but multiple interfaces can be implemented. The code might look something like this:

void main() {
  SuperSaiyan()  // Create a "Fusion Super Saiyan"
      ..guiPaiQiGong() // There is the turtle school of Qigong by Kakarot
      ..faceValueOfPrince(); // Have vegeta's appearance level
}

// Define the Kakarot abstract class
abstract class KakarotAbstract  {
  // Turtle sends qigong
  void guiPaiQiGong();
}

// Define the vegeta abstract class
abstract class VegitoAbstract  {
  // The prince's level of appearance
  void faceValueOfPrince();
}


// Super Saiyans = Kakarote + Vegeta
class SuperSaiyan implements KakarotAbstract.VegitoAbstract{
  @override
  void guiPaiQiGong() {
    print("Turtle send qigong, fire...");
  }

  @override
  void faceValueOfPrince() {
    print("The prince's level of physical appearance is off the charts."); }}Copy the code

The output

Turtle pai Qigong, launch... The level of the prince's appearance is outrageousCopy the code

7.3 MixinsMultiple class inheritance

  • MixinsThe main use is to solvedartThe problem of singleton inheritance, andC++You can have more than one parent class. Similar to the dragon ball fusion, but the number of fusion is not limited, how many people fusion, on

How many people have the same characteristics and abilities.

  • Used to beMixinClass cannot have constructors and can only inherit fromObject
  • By keywordwithConnect one or moremixin

For example, the young out of the river’s lake, want to become a generation of master master high master, must inherit some of the predecessors of the martial arts to be able to walk alone in the world. So prepare the following martial arts stunts:

voidmain() { JumpingEndJunior() .. duGuJiuJiang() .. taXueWuHeng() .. kuiHuaBaoDian(); }// The wind is clear
class XiaoYouZhi {
  // Dugu nine swords
  void duGuJiuJiang() {
    print("Swordsmanship: Dugu nine swordsmanship.); }}// I'm going to have to go
class ChuLiuXiang {
  // There is no trace of snow
  void taXueWuHeng() {
    print("Light work: No trace in snow."); }}// The east is not defeated - sunflower treasure book
class DongFangBuBai {
  // Sunflower treasure book
  void kuiHuaBaoDian() {
    print("The method of terminating children: To practice this skill, one must first practice his own palace."); }}// declare a young out of the river's lake, and then get 3 martial arts myth inheritance - jump ya young
class  JumpingEndJunior extends XiaoYouZhi with ChuLiuXiang.DongFangBuBai {}Copy the code

The output

Swordsmanship: Dugu nine sword, no move win have a move light power: no trace on the snow, cut off children and grandchildren da fa: to practice this power, must first from the palaceCopy the code

7.4 Operator Overwriting

The operator is used by an object. If you want to change the definition of the operator, you can redefine it inside the class. The basic paradigm is:

<type> operator <operator> (arg1, arg2, ...) {
    return <type>}Copy the code

The overridden operators are as follows:

< + | []
> / ^ [] =
< = ~ / & ~
> = * << = =
% >>
“` dart
void main() {
print(Weight(1) > Weight(2));
}

class Weight { double weight;

Weight(this.weight);

Bool operator > (Weight w) {return Weight > w.eight; }}

Enumerations are a finite sequence, a finite set of developer declarations. Since enumerations are finite sets, they are used to qualify variables, that is, variables can only be any element in the set, thus determining to what extent variables are qualified. Dart void main() {Map<Months, String> MonthsMapDesc = {month. January: "1 ", month. February: "2 ", month.march: Months, Months, Months, Months, Months, Months, Months, Months, Months, Months, Months. September: "September ", Months.October:" October ", Months.November: "November ", Months. Print (MonthsMapDesc[month.january]); print(MonthsMapDesc[month.January]); print(MonthsMapDesc[month.January]); } // Declare a month set enumeration, So in this month for the types of variables can only be set in any enum up {January, February, March, April, May, June, out, August, September, October, November, December, }Copy the code

The output

In JanuaryCopy the code

Nine generic

Generics are passing in the desired type as an argument. Then return the corresponding type. Like a list, the map type can be any type when not specified. We can think of it as:

var list = <dynamic> [1."string"{}];// Can be of any type
var map = <dynamic.dynamic> {"foo": 1.2: 2}; // Can be any type of key and any type of value
Copy the code

That is, the expected return value can be of any type. But if you give it a specific type, that is, what type you want it to be. Such as:

var list = <num> [1.2.3]; // The element can only be
var map = <String.num> {"foo": 1."bar": 2}; // Key can only be String and value can only be num
Copy the code

9.1 Why Generics? What are generics good for?

Generics can solve the spatial complexity of types. If you declare a list of costs, if you don’t put type constraints on the list, then the list can be of any type. This makes it impossible to predict that every element in the list space can be of any type, and we just expect a set of numeric types. Generics are used to solve the spatial complexity of types.

9.2 and for what?

The compound types available in DART, such as lists and maps above, can also be used in classes and methods, such as:

  T foo<T>(T arg) {
    return arg;
  }
  print(foo<String> ("hello"));
  print(foo<num> (1));
Copy the code

The output

hello
1
Copy the code

The generic meaning of the foo method above is that a type is expected, the argument must be of that type, and the return value of the expected type is returned;

void main() {
  Bar<String> ("hello").printExpectType();
  Bar("hello").printExpectType(); // < bar does not specify the desired type, but bar does
  // the desired type is initialized after the type is checked during initialization
}

class Bar<T> {
  T arg;
  Bar(T this.arg);

  void printExpectType() {
    print(arg.runtimeType); }}Copy the code

The output

String
String
Copy the code

Bar(“hello”).printExpectType(); It doesn’t specify a type, but it still automatically deduces what type it is. Why? Bar(“hello”).printexpectType (); in the expectexpecttype () Bar(“hello”).printexpecttype () There is a Bar(T this.arg) at initialization, although the type is not passed; Is derived according to the type of the parameter.

The resources

The Basics of Flutter.Dart