🥇
🚩Flutter applications are developed using Dart, an object-oriented, class-defined, single-inheritance language. It has a C-like syntax, can be translated into JavaScript, and supports interfaces, mixins, abstract classes, externalized generics, and optional types.
“
I believe this article will certainly bring you certain harvest 👉
preface
The following is an excerpt from the Dart website. Before learning about Dart, it is important to understand the following concepts:
-
Anything stored in a variable is an object, and all objects are instances of a corresponding class. Both numbers, functions and NULL are objects. All objects inherit from the Object class.
-
Although Dart is strongly typed, Dart can infer types, so type annotations are optional. To specify that no type is required, use the special type Dynamic.
-
Dart supports generics, such as List (a List of integers) or List (a List of objects of any type).
-
Dart supports top-level functions (such as main()) that are bound to classes or objects (static and instance functions, respectively). And support for creating functions (nested or local) within functions.
-
Dart supports top-level variables, which are bound to classes or objects (static and instance variables). Instance variables are sometimes called fields or properties.
-
Unlike Java, Dart does not have the keywords “public,” “protected,” and “private.” If an identifier begins with an underscore (_), it is private relative to the library.
-
An identifier begins with a letter or underscore (_) followed by any combination of letters and numbers.
-
The Dart syntax contains expressions (with run-time values) and statements (with no run-time values). For example, the conditional expression condition? Expr1: The value of expr2 may be expr1 or expr2. Compare this to if-else statements, which have no value. A statement usually contains one or more expressions, whereas expressions cannot contain statements directly.
-
The Dart tool prompts two types of problems: warning _ and _ errors. A warning simply indicates that the code may not work properly, but it does not prevent the program from executing. The error can be a compile-time error or a run-time error. Compile-time errors prevent code execution; Runtime errors cause code to raise an exception (# Exception) during execution.
Dart naming rules
The main() program starts executing the function, which is a specific, required, top-level function.
The Dart variable
Dart is itself a strongly typed language, and any variable has a definite type.
1. Create a variable using var and initialize it
var name = 'lisa'; // The type of the name variable is inferred to be StringCopy the code
In Dart, when a variable is declared with VAR, Dart infer its type at compile time based on the type of the first assigned data, and the type is determined after compile. For example, the above name has been identified as a String, cannot copy another type, otherwise an error will be reported. But you can also change the type of a variable by specifying the type. Such as:
name = 123; / / an errorname = 'Joe'/ / is not an errorCopy the code
2. Explicitly declare the types that can be inferred:
For example, with String,name is determined to be of type String.
String name = 'Joe';
Copy the code
3. Its type can be changed at will.
To specify that no type is required, use the special type Dynamic.
4. Defaults — The default value for uninitialized variables is NULL.
The default value is null even if the variable is a numeric type, because everything is an object in Dart, and numeric types are no exception.
The Dart constants:
Instead of using var or other types, use final or const variables that are never modified.
Variables that are final or const may be omitted.
final
final name = 'Bob';
final String nickname = 'Bobby';
Copy the code
const
const bar = 1000000;
Const double ATM = 1.01325 * bar;Copy the code
Final vs. const
final a=new DateTime.now();
print(a); / / the 15:59:02 2019-05-10. 966122//const a=new DateTime.now(); / / an errorCopy the code
The difference is that a const variable is a compile-time constant, and a final variable is initialized the first time it is used.
Dart naming rules:
-
The variable name must consist of numbers, letters, underscores, and the dollar character ($).
-
Note: Identifiers cannot start with a number
-
Identifiers cannot be reserved words and keywords.
-
The name of a variable is case sensitive. For example, age and age are different variables. In practical use, it is also recommended not to use a word case to distinguish between two variables.
-
Identifiers (variable names) are always given by name: nouns are recommended for variable names and verbs for method names.
Dart data type
String type
1. Several ways to define strings
var str1='this is str1';
String str1='this is str1';
Copy the code
2. String concatenation
String str1='hello';
String str2='Dart';
print("$str1 $str2"); / / hello Dart // Or use the + operatorprint(str1+str2); / / hello DartCopy the code
- Create a multi-line string object with three consecutive single or double quotes:
Numeric types
The Number type can be an int and a double.
Both int and double are subtypes of num. The num types include basic operations +, -, /, and *, as well as abs(), ceil(), and floor(), and other function methods.
1, int must be an integer
int a=123;
a=45;
print(a);
Copy the code
2. A double can be either an integer or a float
Double b = 23.5;
b=24;
print(b);
Copy the code
Boolean type
Dart uses type bool to represent a Boolean value. Dart has only literals true and false that are Boolean types.
bool flag1=true;
print(flag1);
bool flag2=false;
print(flag2); Copy the code
bool flag=true;
if(flag){
print('true');
}else{
print('false'); } Copy the code
List collection type
An Array in Dart is a List object, often referred to as a List.
1. The first way to define a List
var arr1=['aaa'.'bbbb'.'cccc'];
print(arr1);
print(arr1.length);
print(arr1[1]); Copy the code
2. The second way to define a List
The type of the element is uncertain.
var arr2=new List();
arr2.add('Joe');
arr2.add('bill');
arr2.add('Cathy');
print(arr2); print(arr2[2]); // The following method can also be used var arr3=new List<dynamic>(); arr3.add('Joe'); arr3.add(123); print(arr3); Copy the code
Specify that each element of a List is of type String.
main() {
var arr3=new List<String>();
arr3.add('Joe');
arr3.add('lisa'); print(arr3); } Copy the code
The Map type
In general, a Map is an object used to associate keys and values. Keys and values can be any type of object. A key can only appear once in a Map object. But value can appear more than once. Dart maps are implemented through Map literals and Map types.
The first way to define a Map
var person={
"name":"Zhang"."age": 20."work": ["Programmer"."Take out"]
};
print(person); print(person["name"]); print(person["age"]); print(person["work"]); Copy the code
The second way to define a Map
var p=new Map();
p["name"] ="Bill";
p["age"] = 22;p["work"] = ["Programmer"."Take out"];
print(p); print(p["age"]); Copy the code
The Set type
A Set is an unordered and unrepeatable Set, so it cannot be indexed to get a value
var s=new Set();
s.add('banana');
s.add('apple');
s.add('apple');
print(s); //{banana, apple}print(s.toList()); //[banana, apple] List myList=['banana'.'apple'.'watermelon'.'banana'.'apple'.'banana'.'apple']; var s=new Set(); Copy the code
Can be used for array de-duplication
List myList=['banana'.'apple'.'watermelon'.'banana'.'apple'.'banana'.'apple'];
var s=new Set();
s.addAll(myList);
print(s); //{banana, apple, watermelon} print(s.toList()); //[banana, apple, watermelon]Copy the code
Other types of
Runes
Rune is a UTF-32 encoded string. It can be converted from text to emoticons or to represent specific words.
Symbols
The Symbol object represents the operator or identifier declared in the Dart program.
Dart common operator
Arithmetic operator
int a=13;
int b=5;
print(a+b); / / addprint(a-b); / /print(a*b); / / byprint(a/b); / / in addition toprint(a%b); / / to take overprint(a~/b); / / integerCopy the code
Relational operator
int a=5;
int b=3;
print(a==b); // Check whether it is equal print(a! =b); // Check if the value is unequal print(a>b); // Check whether the value is greater than print(a<b); // Determine whether the value is less than print(a>=b); // Check whether the value is greater than or equal to print(a<=b); // Check whether the value is less than or equal toCopy the code
The assignment operator
Assign values to variables using =. Use?? The = operator assigns to a variable only if it is null.
int b=6;
b?? = 23;print(b); / / 6
int b; b?? = 23;print(b); / / 23Copy the code
If a is empty, then b=10;
var a=22;
var b= a ?? 10;
print(b); / / 22Copy the code
Type conversion
Converts Number toString toString()
String类型转成Number类型 int.parse()
A string is converted to a number
String str='123';
var myNum=int.parse(str);
print(myNum is int);
String str='123.1'; var myNum=double.parse(str); print(myNum is double); String price='12'; var myNum=double.parse(price); print(myNum); print(myNum is double); Copy the code
Try… A lot of catch
String price=' ';
try{
var myNum=double.parse(price);
print(myNum);
}catch(err){ print(0); } Copy the code
The value is converted to a string
var myNum=12;
var str=myNum.toString();
print(str is String);
Copy the code
Other types are converted to Booleans
//isEmpty: checks whether the string isEmpty
var str=' ';
if(str.isEmpty){
print('STR empty');
}else{ print('STR is not empty'); } var myNum=123; if(myNum==0){ print('0'); }else{ print(Not '0'); } var myNum; if(myNum==0){ print('0'); }else{ print(Not '0'); } var myNum; if(myNum==null){ print('empty'); }else{ print('is not empty); } Copy the code
Dart collection types in detail
List of common attributes and methods:
List attributes:
List myList=['banana'.'apple'.'watermelon'];
print(myList.length);
print(myList.isEmpty);
print(myList.isNotEmpty);
print(myList.reversed); // Sort the list backwards var newMyList=myList.reversed.toList(); print(newMyList); Copy the code
List of methods:
List myList=['banana'.'apple'.'watermelon'];
myList.add('peach'); // Add data add one
myList.addAll(['peach'.'grapes']); // Concatenate an array
print(myList); print(myList.indexOf(Apple x Apples)); // if the index is not found, return -1 myList.remove('watermelon'); // Delete the specific value passed in myList.removeAt(1); // Delete the index value passed in print(myList); myList.fillRange(1, 2,'aaa'); / / modify myList.fillRange(1, 3,'aaa'); myList.insert(1,'aaa'); // Insert one at the specified position myList.insertAll(1, ['aaa'.'bbb']); // Insert multiple specified positions into the List var str=myList.join(The '-'); // List is converted to a string print(str); print(str is String); //true var list=str.split(The '-'); // String is converted to List Var arr = (11,22,33);var arr2 = arr.toList(); // Other types are converted to ListCopy the code
The method of traversing a List is forEach map where any every, which is the same as ES6.
Set:
Its main function is to remove the array duplicate content; A Set is an unordered and unrepeatable Set, so it cannot be retrieved by index;
var s=new Set();
s.add('banana');
s.add('apple');
s.add('apple');
print(s); //{banana, apple} print(s.toList()); Copy the code
List myList=['banana'.'apple'.'watermelon'.'banana'.'apple'.'banana'.'apple'];
var s=new Set();
s.addAll(myList); print(s); print(s.toList()); Copy the code
s.forEach((value)=>print(value));
Copy the code
Map: A Map is an unordered key-value pair:
Common attributes:
Map person={
"name":"Zhang"."age": 20."sex":"Male"
};
print(person.keys.toList()); print(person.values.toList()); print(person.isEmpty); // Whether it is emptyprint(person.isNotEmpty); // Whether it is not nullCopy the code
Common methods:
Map person={
"name":"Zhang". "age": 20. "sex":"Male"
};
Person.addall ({// Merge the map to add attributes to the map "work": ['Knock code'.'Take out']. "height": 160}); print(person); person.remove("sex"); // Delete data for the specified keyprint(person); print(person.containsValue('Joe')); // View the value returned within the maptrue/false person.forEach((key,value){ print("$key---$value"); }); Copy the code
The Dart function
Dart is a true object-oriented language, even its functions are objects and have their type Function.
Custom methods
No return value: void indicates that the method has no return value.
void printInfo() { print('I'm a custom method');
}
Copy the code
Returns a value of type int
int getNum() { var myNum=123;
return myNum;
}
Copy the code
Return string type
String printUserInfo() { return 'this is str';
}
Copy the code
Return List
List getList() { return ['111'.'2222'.'333'];
}
Copy the code
The main () function
Any application must have a top-level main() function as an entry point to the application service. The main() function returns a null value and takes an optional List.
void main() {
print('Call system built-in methods');
printInfo();
var n=getNum(); print(n); print(printUserInfo()); print(getList()); print(getList()); } Copy the code
Method scope
void get() {
aaa() {
print(getList());
print('aaa'); } aaa(); } // aaa(); Error writing get(); // Call the method} Copy the code
Methods the reference
Defines a method that evaluates the sum of all numbers from 1 to this number and returns an int.
Int sumNum(int n){// The received argument must be of type int, otherwise an error is reported var sum=0;
for(var i=1; i<=n; i++) {
sum+=i;
} return sum; } var sum=sumNum(5); Copy the code
Define a method and print the user information. The return value is String and the arguments are String and int.
String printUserInfo(String username,int age){// Line parameter return "Name:$username---年龄:$age";
}
print(printUserInfo('Joe', 20)); / / argumentsCopy the code
Defines a method that takes optional parameters
Wrap a set of function arguments, mark them with [] as optional positional arguments, and place them at the end of the argument list:
String printUserInfo(String username,[int age]){// Line parameter
if(age! =null){ return "Name:$username---年龄:$age";
}
return "Name:$username-- Age confidential"; } print(printUserInfo('Joe', 21)); / / arguments print(printUserInfo('Joe')); Copy the code
Define a method with default parameters
If the method is called without passing an optional parameter, the default parameter can be used.
String printUserInfo(String username,[String sex='male',int age]){// line argument
if(age! =null){ return "Name:$usernameGender: -$sex- age:$age";
}
return "Name:$usernameGender: -$sex-- Age confidential."; } print(printUserInfo('Joe')); print(printUserInfo('xiao li'.'woman')); print(printUserInfo('xiao li'.'woman', 30));Copy the code
Defines a method for naming parameters
When defining functions, use {param1, param2… }, at the end of the parameter list, to specify named parameters. Such as:
When calling a function, you can use the specified named arguments. For example, paramName: value
String printUserInfo(String username,{int age,String sex='male'}) {/ / line parameters
if(age! =null){ return "Name:$usernameGender: -$sex- age:$age";
}
return "Name:$usernameGender: -$sex-- Age confidential."; } print(printUserInfo('Joe',age:20,sex:'unknown')); Copy the code
The difference between the method of naming and optional parameters:
- The named parameter method uses {};
- Optional arguments use [];
- Named parameter methods must pass values based on the field name of the parameter;
Optional parameters can be named parameters or positional parameters, but a parameter can be modified in either way.
Functions are first-class objects
A function can take arguments to another function. Such as:
/ / methodfn1() { print('fn1');
}
/ / methodfn2(fn){ fn(); } // call fn2 and pass fn1 as an argumentfn2(fn1); Copy the code
Anonymous methods
Most functions have names, such as main() and getInfo(). It is also possible to create functions without names, which are called anonymous functions.
Anonymous functions and named functions look similar – arguments can be passed in parentheses, and arguments are easily separated.
var printNum=(int n, int m){
print(m*n);
};
PrintNum (12, 16); / / 240Copy the code
Self-executing method
((int n){
print(n);
print('I'm self-executing method');
}) (12);Copy the code
Method recursion
Request the sum of values up to 100
var sum=0;
fn(int n){
sum+=n;
if(n==0){ return; } fn(n-1); } fn(100); print(sum); Copy the code
closure
A closure is a function object that can access variables in its lexical scope even if the function object is called outside its original scope.
/// returns a function whose arguments are added to [addBy].Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
void main() { // create a function that adds 2. var add2 = makeAdder(2); // create a function that adds 4. var add4 = makeAdder(4); print(add2(3) == 5); //true print(add4(3) == 7); //true } Copy the code
Dart in the class
Everything in Dart is an Object, and all objects inherit from the Object class.
Dart is an object-oriented language that uses classes and single inheritance. All objects are instances of classes, and all classes are subclasses of Object.
Dart defines classes using classes
class Person{
String name="Zhang";
int age=23;
void getInfo() { // print("$name----$age"); // same as the following print("${this.name}----${this.age}"); } void setInfo(int age){ this.age=age; } } void main() { // instantiate the class Person p1=new Person(); print(p1.name); / / zhang SAN p1.setInfo(28); p1.getInfo(); / / zhang SAN - 28} Copy the code
The default constructor for a class in Dart
Define a default constructor
class Person{
String name='Joe';
int age=20;
// Default constructor Person() { print('This is what's inside the constructor and this method fires when it instantiates.'); } void printInfo() { print("${this.name}----${this.age}"); } } void main() { // instantiate the class Person p1=new Person(); print(p1.name); p1.printInfo(); } Copy the code
Pass parameters to the constructor
class Person{
String name;
int age;
// Default constructor Person(String name,int age){ this.name=name; this.age=age; } void printInfo() { print("${this.name}----${this.age}"); } } void main() { // instantiate the class Person p1=new Person('Joe', 20); print(p1.name); / / zhang SAN p1.printInfo(); / / zhang SAN - 20} Copy the code
The constructor is short for:
class Person{
String name;
int age;
// Short for the default constructor Person(this.name,this.age); void printInfo() { print("${this.name}----${this.age}"); } } void main() { // instantiate the class Person p1=new Person('Joe', 20); print(p1.name); / / zhang SAN p1.printInfo(); / / zhang SAN - 20} Copy the code
Named constructors in Dart
Dart has only one default constructor, but can have multiple named constructors.
class Person{
String name;
int age;
// Short for the default constructor Person(this.name, this.age); // I am the named constructor Person.now() { print('I'm a named constructor'); } // Pass parameters to the named constructor Person.setInfo(String name, int age){ this.name=name; this.age=age; } void printInfo() { print("${this.name}----${this.age}"); } } void main() { Person p1=new Person('Joe', 20); The default constructor is called when the class is instantiated by default Person p2=new Person.now(); // Name the constructor Person p3=new Person.setInfo('bill', 30);p1.printInfo(); / / zhang SAN - 20p3.printInfo(); / / li si - 30 } Copy the code
Private methods and private properties in Dart
Unlike other object-oriented languages, Dart does not have the public private protected access modifier in Data
But we can use _ to make a property or method private.
I'll create a separate Animal class
class Animal{
String _name; // Private attributes int age;
// Short for the default constructor Animal(this._name,this.age); void printInfo() { print("${this._name}----${this.age}"); } String getName() { return this._name; } void _run() { print('This is a private method'); } execRun() {this._run(); // Method calls to each other within a class } } Copy the code
// Call private methods
import 'lib/Animal.dart';
void main() {
Animal a=new Animal('dog', 3);
print(a.getName()); a.execRun(); // Call private methods indirectly } Copy the code
The use of getter and setter modifiers in a class
class Rect{
num height;
num width;
Rect(this.height,this.width);
get area{ return this.height*this.width; } set areaHeight(value){ this.height=value; } } void main() {The Rect r = new the Rect (10, 4); // print("The area:${r.area()}"); r.areaHeight=6; print(r.area); / / 24 } Copy the code
Initialize instance variables in Dart
In Dart we can also initialize instance variables before the constructor body is run.
class Rect{
int height;
int width;
Rect():height=2,width=10{
print("${this.height}---${this.width}"); //2---10 } getArea() { return this.height*this.width; } } void main() { Rect r=new Rect(); print(r.getArea()); / / 10 } Copy the code
Dart implements multiple interfaces in one class
Define two abstract classes A and B. The properties and methods defined in the abstract class must be implemented in the interface.
abstract class A{
String name;
printA();
}
abstract class B{ printB(); } class C implements A,B{ @override String name; @override printA() { print('printA'); } @override printB() { // TODO: implement printB return null; } } Copy the code
void main() {
C c=new C();
c.printA(); //printA
} Copy the code
The Dart in mixins
Mixins can be used in Dart to achieve something like multiple inheritance.
Because mixins use conditions [DARt2.x version] :
Mixins can only inherit from Objects, not other classes.
Classes that are mixins cannot have constructors.
3. A class can mixins multiple mixins classes.
Mixins are not inheritance, nor are they interfaces, but rather a completely new feature
class A {
String info="this is A";
void printA() { print("A");
}
} class B { void printB() { print("B"); } } class C with A,B{ } void main() { var c=new C(); c.printA(); c.printB(); print(c.info); } Copy the code
Inheritance of static member operator classes for classes in Dart
Dart class static members static methods
Static members in Dart:
1. Use the static keyword to implement class-level variables and functions
2. Static methods cannot access non-static members. Non-static methods can access static members
Define a class with static properties and methods
class Person {
static String name = 'Joe';
static void show() {
print(name);
}
} main() { print(Person.name); Person.show(); } Copy the code
Object operators in Dart
- ? Conditional operators (Understanding)
- As type Conversion
- Is Type Judgment
- . Cascade operation
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}"); } } Copy the code
? Conditional operator
If p exists, the printInfo method is called.
Person p=new Person('Joe', 20);
p? .printInfo();Copy the code
Is Judgment type
Person p=new Person('Joe', 20);
if(p is Person){
p.name="Bill";
}
p.printInfo(); print(p is Object); Copy the code
As type Conversion
p1=new Person("Zhang SAN 1 ', 20);
// p1.printInfo();
(p1 as Person).printInfo();
Copy the code
. Cascade operation (concatenation)
Person p1=new Person("Zhang SAN 1 ', 20);
p1.printInfo();
p1.name='Joe 222';
p1.age=40; p1.printInfo(); Copy the code
Is equivalent to
Person p1=new Person("Zhang SAN 1 ', 20);
p1.printInfo();
p1.. name="Bill"
..age=30 ..printInfo(); Copy the code
Inheritance of the Dart class – Simple inheritance
Class inheritance in Dart: 1. Subclasses inherit from their parent class using the extends keyword
Subclasses inherit properties and methods visible from their parent class, but not constructors
3. Subclasses can override getters and setters for the methods of their parent class
class Person {
String name='Joe';
num age=20;
void printInfo() {
print("${this.name}---${this.age}");
} } class Web extends Person{ } main() { Web w=new Web(); print(w.name); w.printInfo(); } Copy the code
Pass arguments to the parent constructor
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}"); } } class Web extends Person{ Web(String name, num age) : super(name, age){ } } main() { Web w=new Web('Joe', 12); w.printInfo(); } Copy the code
You can also pass arguments to your own class when inheriting
class Web extends Person{
String sex;
Web(String name, num age,String sex) : super(name, age){
this.sex=sex;
}
run() { print("${this.name}---${this.age}--${this.sex}"); } } Web w=new Web('Joe', 12,"Male"); w.printInfo(); Copy the code
Pass parameters to the named constructor
class Person {
String name;
num age;
Person(this.name,this.age);
Person.xxx(this.name,this.age);
void printInfo() { print("${this.name}---${this.age}"); } } class Web extends Person{ String sex; Web(String name, num age,String sex) : super.xxx(name, age){ this.sex=sex; } run() { print("${this.name}---${this.age}--${this.sex}"); } } main() { Web w=new Web('Joe', 12,"Male"); w.printInfo(); w.run(); } Copy the code
The inheritance of the Dart class overrides the methods of the parent class
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}"); } work() { print("${this.name}At work..."); } } class Web extends Person{ Web(String name, num age) : super(name, age); run() { print('run'); } // Override the parent methodOverride // It is recommended to override the parent method with @override void printInfo() { print("Name:${this.name}- age:${this.age}"); } @override work() { print("${this.name}Is to write code."); } } main() { Web w=new Web('bill', 20); w.printInfo(); w.work(); } Copy the code
Dart calls the parent class’s methods from within the class
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}"); } work() { print("${this.name}At work..."); } } class Web extends Person{ Web(String name, num age) : super(name, age); run() { print('run'); super.work(); // call a method from the parent class } // Override the parent methodOverride // It is recommended to override the parent method with @override void printInfo() { print("Name:${this.name}- age:${this.age}"); } } main() { Web w=new Web('bill', 20); // w.printInfo(); w.run(); } Copy the code
Abstract class polymorphism and interfaces in Dart
The difference between extends and implements:
1. Extends extends an abstract class if we want to reuse methods from an abstract class and constrain our classes with abstract methods
2. Implements abstract classes, if only as a standard
Abstract classes in Dart
Dart abstract classes are used to define standards, and subclasses can inherit abstract classes or implement abstract class interfaces.
1. Abstract classes are defined by the abstract keyword
2. Dart abstract methods cannot be declared with abstract. Dart methods without a method body are called abstract methods.
If a subclass inherits an abstract class, it must implement its abstract methods
If you use an abstract class as an interface implementation, you must implement all properties and methods defined in the abstract class.
5. An abstract class cannot be instantiated, only subclasses that inherit it can
abstract class Animal{
eat(); // Abstract methodsrun(); // Abstract methods printInfo() { print('I'm a normal method in an abstract class.');
} } class Dog extends Animal{ @override eat() { print('The dog is eating a bone'); } @override run() { // TODO: implement run print('The dog is running'); } } class Cat extends Animal{ @override eat() { // TODO: implement eat print('The kitten is eating the mouse'); } @override run() { // TODO: implement run print('The kitten is running'); } } main() { Dog d=new Dog(); d.eat(); d.printInfo(); Cat c=new Cat(); c.eat(); c.printInfo(); // Animal a=new Animal(); // An abstract class cannot be instantiated directly } Copy the code
Polymorphism in the Dart
-
It is possible to assign a pointer of a subclass type to a pointer of a superclass type. The same function call may have different execution effects.
-
An instance of a subclass is assigned to a reference to the parent class.
-
Polymorphism is when a parent class defines a method and does not implement it, leaving it to its subclasses, each of which behaves differently.
abstract class Animal{
eat(); // Abstract methods}
class Dog extends Animal{
@override eat() { print('The dog is eating a bone'); } run() { print('run'); } } class Cat extends Animal{ @override eat() { print('The kitten is eating the mouse'); } run() { print('run'); } } main() { Animal d=new Dog(); d.eat(); Animal c=new Cat(); c.eat(); } Copy the code
Interfaces in Dart
Dart interfaces do not have the interface keyword. Instead, ordinary or abstract classes can be implemented as interfaces.
The implements keyword is also used.
Dart’s interface, however, is a bit odd. If you implement a generic class, you’ll need to overwrite all the methods of the generic class and the attributes in the abstraction.
And because abstract classes can define abstract methods that ordinary classes can’t, it’s common to use abstract classes if you want to implement things like Java interfaces.
It is recommended to define interfaces using abstract classes.
Mysql MSSQL mongodb mysql MSSQL mongodb mysql MSSQL mongodb
Abstract class Db{// as an interface interface: conventions, specificationsString uri; // Database link address add(String data);
save();
delete();
} class Mysql implements Db{ @override String uri; Mysql(this.uri); @override add(data) { // TODO: implement add print('This is mysql add method'+data); } @override delete() { // TODO: implement delete return null; } @override save() { // TODO: implement save return null; } remove() { } } class MsSql implements Db{ @override String uri; @override add(String data) { print('This is the add method of MSSQL'+data); } @override delete() { // TODO: implement delete return null; } @override save() { // TODO: implement save return null; } } main() { Mysql mysql=new Mysql('xxxxxx'); mysql.add('1243214'); } Copy the code
A class in Dart implements multiple interfaces and Mixins in Dart
A class implements multiple interfaces in Dart:
abstract class A{
String name;
printA();
}
abstract class B{ printB(); } class C implements A,B{ @override String name; @override printA() { print('printA'); } @override printB() { // TODO: implement printB return null; } } void main() { C c=new C(); c.printA(); } Copy the code
The Dart in mixins
Mixins are a way to reuse class code at different levels without inheritance.
Mixins are used by using with followed by one or more mixins.
Because the conditions for mixins change with Dart releases, here are the conditions for using mixins in DART2.x:
Mixins can only inherit from Objects, not other classes.
Classes that are mixins cannot have constructors.
3. A class can mixins multiple mixins classes.
Mixins are not inheritance, they are not interfaces, they are a completely new feature;
class A {
String info="this is A";
void printA() { print("A");
}
} class B { void printB() { print("B"); } } class C with A,B{ } void main() { var c=new C(); c.printA(); c.printB(); print(c.info); } Copy the code
Pass a parameter to the parent class
class Person{
String name;
num age;
Person(this.name,this.age);
printInfo() { print('${this.name}----${this.age}'); } void run() { print("Person Run"); } } class A { String info="this is A"; void printA() { print("A"); } void run() { print("A Run"); } } class B { void printB() { print("B"); } void run() { print("B Run"); } } class C extends Person with B,A{ // Pass a parameter to the parent class C(String name, num age) : super(name, age); } void main() { var c=new C('Joe', 20); c.printInfo(); c.run(); } Copy the code
Types of mixins in Dart
A mixins type is a subtype of its superclass.
class A {
String info="this is A";
void printA() { print("A");
}
} class B { void printB() { print("B"); } } class C with A,B{ } void main() { var c=new C(); print(c is C); //true print(c is A); //true print(c is B); //true } Copy the code
Generics in Dart
Generics address the reuse of class interface methods and support for non-specific data types (type validation)
Generic methods in Dart
Only string data can be returned
String getData(String value){
return value;
}
Copy the code
Both string and int are supported (code redundancy)
String getData1(String value){
return value;
}
int getData2(int value){
return value; } Copy the code
Returning both string and number without specifying a type solves this problem
getData(value){
return value;
}
Copy the code
Not specifying a type abandons type checking. What we want to implement now is to return what is passed in. For example, the number type must be returned when the number type is passed in. The string type must be returned when the string type is passed in
getData<T>(T value){
return value;
}
print(getData<int>(12)); // The incoming type is the same as the return typeCopy the code
Generic classes in Dart
You can add an int or String to an array.
class PrintClass<T>{
List list=new List<T>();
void add(T value){
this.list.add(value);
}
void printInfo() { for(var i=0; i<this.list.length; i++){ print(this.list[i]); } } } PrintClass p=new PrintClass<int>(); p.add(12); p.add(23); p.printInfo(); Copy the code
Generic interfaces in Dart
Data cache functions: file cache, and memory cache. Memory and file caching are implemented according to interface constraints.
1, define a generic interface constraint that subclasses that implement it must have getByKey(key) and setByKey(key,value)
SetByKey = setByKey (); setByKey = setByKey ()
abstract class Cache<T>{
getByKey(String key);
void setByKey(String key, T value);
}
class FlieCache<T> implements Cache<T>{ @override getByKey(String key) { return null; } @override void setByKey(String key, T value) { print("I am file cache key=${key} value=${value}The data is written to the file."); } } class MemoryCache<T> implements Cache<T>{ @override getByKey(String key) { return null; } @override void setByKey(String key, T value) { print("I am memory cache key=${key} value=${value}- Write to memory"); } } void main() { MemoryCache m=new MemoryCache<Map>(); m.setByKey('index', {"name":"Zhang"."age": 20});} Copy the code
The Dart asynchronous
Dart is a language based on a single-threaded model. Dart also has its own process (or thread) mechanism called ISOLATE. The APP startup entry main function is an ISOLATE.
The Dart thread has one message loop (Event Loop) and two queues (Event Queue and MicroTask Queue).
-
The event queue contains all external events: I/O, Mouse Events, Drawing Events, timers, and messages between isolate. All new events (I/O, Mouse Events, Drawing Events, Timers, and ISOLATE messages) added to the ISOLATE are queued in the Event Queue for execution.
-
Microtask Queue queues only in the current ISOLATE task queues and has a higher priority than Event Queue.
If a microtask is inserted into an event, the current event can be queued to execute the microtask. Without MicroTask, there is no way to jump the queue. That is, the existence of a MicroTask Queue provides Dart with a solution for queue-jumping.
When the main method is finished and exits, the Event Loop executes microtasks in FIFO(first in, first out) order. When all microtasks are finished, it takes events from the Event Queue and executes them. This is repeated until both queues are empty, as shown in the following flow chart:
Asynchronous execution
So how do you make your code execute asynchronously in Dart? It is simple to place code to be executed asynchronously in a microtask queue or event queue.
- ScheduleMicrotask can be called to make code execute asynchronously as a microtask
scheduleMicrotask((){
print('a microtask');
});
Copy the code
- You can call timer.run to make your code execute asynchronously as an Event
Timer.run((){
print('a event');
});
Copy the code
Just like JS, it’s easy to fall into “Callback hell” using only Callback functions for asynchracy. To avoid this problem, JS introduced promises. Similarly, Dart introduces Future.
Future
A Future, much like a Promise in JavaScript, represents the final completion (or failure) of an asynchronous operation and the representation of its resulting value. In simple terms, it is used to handle asynchronous operations, executing the successful operation if the asynchronous process succeeds, and catching errors or stopping subsequent operations if the asynchronous process fails. A Future only has one outcome, either success or failure.
To use a Future, dart. Async is introduced
import 'dart:async';
Copy the code
Create a Future that runs immediately in the event queue:
Future(() => print('Future running in Event Queue now'));
Copy the code
Future.then
Future.delayed creates a delayed task (the actual item could be a truly time-consuming task, such as a network request) that returns the resulting string “Hi world!” after 2 seconds with future.delayed. Then we receive the asynchronous result in then and print the result:
Future.delayed(new Duration(seconds: 2),(){
return "hi world!";
}).then((data){
print(data);
});
Copy the code
Future.catchError
If an error occurs in an asynchronous task, we can catch the error in catchError.
Future.delayed(new Duration(seconds: 2),(){
//return "hi world!";
throw AssertionError("Error");
}).then((data){
// Successful execution will go here print("success"); }).catchError((e){ // Execution failure leads to this print(e); }); Copy the code
The then method also has an optional argument, onError, which we can also use to catch exceptions:
Future.delayed(new Duration(seconds: 2), () {
//return "hi world!";
throw AssertionError("Error");
}).then((data) {
print("success");
}, onError: (e) { print(e); }); Copy the code
Future.whenComplete
Sometimes, we have situations where something needs to be done whether an asynchronous task succeeds or fails.
Future.delayed(new Duration(seconds: 2),(){
//return "hi world!";
throw AssertionError("Error");
}).then((data){
// Successful execution will go here print(data); }).catchError((e){ // Execution failure leads to this print(e); }).whenComplete((){ // Success or failure will lead us here}); Copy the code
Future.wait
Sometimes, we need to wait for multiple asynchronous tasks to complete before doing something.
We simulated two asynchronous tasks of data acquisition by simulating future.delayed. When both asynchronous tasks were successfully executed, the results of the two asynchronous tasks were spliced and printed.
Future.wait([
// Return the result after 2 seconds Future.delayed(new Duration(seconds: 2), () {
return "hello";
}),
// Return the result after 4 seconds Future.delayed(new Duration(seconds: 4), () { return " world"; }) ]).then((results){ print(results[0]+results[1]); }).catchError((e){ print(e); }); Copy the code
Async/await
The async/await functionality and usage in Dart and JavaScript async/await are exactly the same.
The method of returning the Future through the Future callback avoids layers of nesting, but there is still a layer of callback. Is there a way to perform asynchronous tasks like writing synchronous code without using callbacks? The answer is yes, we need to use async/await.
task() async {
try{
String id = await login("alice"."* * * * * *");
String userInfo = await getUserInfo(id);
await saveUserInfo(userInfo);
// Perform the following operations } catch(e){ // Error handling print(e); } } Copy the code
- Async is used to indicate that a function is asynchronous. The defined function returns a Future object. Callbacks can be added using the then method.
- “Await” is followed by a Future, which means to wait for the asynchronous task to complete and then proceed. Await must appear inside async function.
Reference documentation
Dart Official Documentation
Introduction to the Dart language in the Flutter documentation
Hope to see here friends can move start a thumbs-up 👍 oh, your support is the biggest encouragement to me 💪!!