Dart (2)

Time:2020-3-4

Foreword 1: I will update some columns of flutter text tutorials in succession in the next period

Update progress:At least two articles per week;

Update location:The first time is in the official account, and the second day is updated in nuggets and places of thought.

More communication:You can add my wechat 372623326 and follow my micro blog: Code why

I hope you canHelp forward, click to seeGive me more creative power.

1、 Operators

Here, I only list operators that are special to other languages, because some operators are too simple to waste time, such as +, -, + =, = =.

You may wonder why dart has so many special operators?

You should firmly believe that all these special operators are designed to make our development more convenient, rather than make our coding more complex.

1.1. Division, integer division and modular operation

Let’s take a look at division, division and modulo

var num = 7;
Print (Num / 3); // division, result 2.3333
Print (Num ~ / 3); // integer division, result 2;
Print (Num% 3); // module fetching, result 1;

1.2.? = assignment operation

Dart has an assignment operator that many languages do not have:

  • When the variable is null, the following is used for the assignment.
  • When the variable has a value, use its original value.
main(List<String> args) {
  var name1 = 'coderwhy';
  print(name1);
  // var name2 = 'kobe';
  var name2 = null;
  name2 ??= 'james'; 
  Print (Name2); // when Name2 is initialized to Kobe, the result is Kobe. When initialization is null, the value of James is assigned
}

1.3. Conditional operator:

Dart contains conditional operators that are always special:expr1 ?? expr2

  • If expr1 is null, the result of expr2 is returned;
  • If expr1 is not null, use the result of expr1 directly.
var temp = 'why';
var temp = null;
var name = temp ?? 'kobe';
print(name);

1.4. Cascade syntax:

  • Sometimes, we want to operate on an object continuously. At this time, we can use cascading syntax
class Person {
  String name;

  void run() {
    print("${name} is running");
  }

  void eat() {
    print("${name} is eating");
  }

  void swim() {
    print("${name} is swimming");
  }
}

main(List<String> args) {
  final p1 = Person();
  p1.name = 'why';
  p1.run();
  p1.eat();
  p1.swim();

  final p2 = Person()
              ..name = "why"
              ..run()
              ..eat()
              ..swim();
}

2、 Process control

It’s similar to the features of most languages. I won’t go into details here. Just have a look.

2.1. If and else

Same as other languages

Here’s a note: non null true or non-zero true is not supported. There must be an explicit bool type

  • Let’s take a look at the following judgment of null name

Dart (2)

2.2. Cyclic operation

Basic for loop

for (var i = 0; i < 5; i++) {
  print(i);
}

For in traverses list and set types

var names = ['why', 'kobe', 'curry'];
for (var name in names) {
  print(name);
}

While and do while are consistent with other languages

Break and continue are the same

2.3. switch-case

Common switch use

  • Note: each case statement must end with a break by default
main(List<String> args) {
  var direction = 'east';
  switch (direction) {
    case 'east':
      Print ('east ');
      break;
    case 'south':
      Print ('south ');
      break;
    case 'west':
      Print ('west ');
      break;
    case 'north':
      Print ('north ');
      break;
    default:
      Print ('Other direction ');
  }
}

3、 Classes and objects

Dart is an object-oriented language. A very important concept in object-oriented is class, which produces object.

In this section, we will specifically learn classes and objects, but dart has carried out many features that are not available in other languages, so I will spend a long time here to explain them.

3.1. Definition of class

In dart, to define a classClass keyword

A class usually consists of two parts: member and method.

The pseudocode defining the class is as follows:

Class class name{
  Type member name;
  Return value type method name (parameter list){
    Method body
  }
}

Write a simple person class:

  • Here is a note:When we use properties (member / instance variables) in methods,No this
  • In DART’s development style, when attributes are usually used in methods, theEllipsis thisBut there arename conflictAt that time,This cannot be omitted
class Person {
  String name;

  eat() {
    Print ('$name is eating');
  }
}

Let’s use this class to create corresponding objects:

  • Note: starting with dart2, the new keyword can be omitted.
main(List<String> args) {
  //1. Create object of class
  Var P = new person(); // you can also create it by using person()

  //2. Assign values to the properties of the object
  p.name = 'why';

  //3. Method of calling object
  p.eat();
}

3.2. Construction method

3.2.1. General construction method

We know that when an object is created through a class, the constructor of that class is called.

  • When classNo construction method specifiedWill have one by defaultConstruction method without parameters
  • In the previous person, we are calling this constructor

We can also define our own construction methods according to our own needs:

  • Note 1:When you have your own construction method,Default constructor will fail, not available

    • Of course, you may want to write a default constructor explicitly, but it will conflict with our custom constructor;
    • That’s because dart himselfOverloading of functions is not supported(the names are the same, and the parameters are different).
  • Note two:Here I also implement the toString method
class Person {
  String name;
  int age;

  Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  @override
  String toString() {
    return 'name=$name age=$age';
  }
}

In addition, when implementing a constructor, the usual thing to do is toparametertoattributeassignment

To simplify this process, dart provides a more conciseGrammatical sugar form.

The above construction method can be optimized as follows:

Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  // equal to
  Person(this.name, this.age);

3.2.2. Naming construction method

But in development, we really want to implement more construction methods. What should we do?

  • Because overloading of methods (functions) is not supported, we cannot create a constructor with the same name.

We need to useNamed construction method:

class Person {
  String name;
  int age;

  Person() {
    name = '';
    age = 0;
  }
    //Named construction method
  Person.withArgments(String name, int age) {
    this.name = name;
    this.age = age;
  }

  @override
  String toString() {
    return 'name=$name age=$age';
  }
}

//Create objects
var p1 = new Person();
print(p1);
var p2 = new Person.withArgments('why', 18);
print(p2);

In later development, we can also use the named construction method to provide a more convenient way to create objects:

  • For example, in development, we often need to turn a map into an object, which can provide the following construction methods
//New construction method
    Person.fromMap(Map<String, Object> map) {
    this.name = map['name'];
    this.age = map['age'];
  }

    //Create objects using the above construction method
  var p3 = new Person.fromMap({'name': 'kobe', 'age': 30});
  print(p3);

3.2.3. Initialization list

Let’s redefine a class point, pass in X / y, and get their distance:

class Point {
  final num x;
  final num y;
  final num distance;

  //Wrong writing
  // Point(this.x, this.y) {
  //   distance = sqrt(x * x + y * y);
  // }

  //Correct writing
  Point(this.x, this.y) : distance = sqrt(x * x + y * y);
}

The above method of initializing variables is calledInitializer list

3.2.4. Redirection construction method

In some cases, we want to call another constructor in one constructor, which can be used at this timeRedirection construction method

  • In one constructor, call another constructor (Note: This is called after the colon)
class Person {
  String name;
  int age;

  Person(this.name, this.age);
  Person.fromName(String name) : this(name, 0);
}

3.2.5. Constant construction method

In some cases,When the same value is passed in, we hopeReturn the same object, at this time, you can use the constant construction method

By default, when creating an object, even if the same parameters are passed in, the created object is not the same. See the following code:

  • Here we useIdentity (object 1, object 2)Function to determine whether two objects are the same object:
main(List<String> args) {
  var p1 = Person('why');
  var p2 = Person('why');
  print(identical(p1, p2)); // false
}

class Person {
  String name;

  Person(this.name);
}

However, if the construction method is prefixedConst to modify, then you can ensure that the same parameter and created object are the same

  • Such a construction method is calledConstant construction method
main(List<String> args) {
  var p1 = const Person('why');
  var p2 = const Person('why');
  print(identical(p1, p2)); // true
}

class Person {
  final String name;

  const Person(this.name);
}

There are some points for attention in constant construction method:

  • Note 1:In a class with constant constructor, allMember variable must be final decorated.
  • Note two:In order to create the same object through constant construction method, it is no longer usednewKeyword, use const keyword instead

    • If the result is assigned to a const decorated identifier, const can be omitted

3.2.6. Factory construction method

Dart provides the factory keyword to get objects through the factory

main(List<String> args) {
  var p1 = Person('why');
  var p2 = Person('why');
  print(identical(p1, p2)); // true
}

class Person {
  String name;

  static final Map<String, Person> _cache = <String, Person>{};

  factory Person(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final p = Person._internal(name);
      _cache[name] = p;
      return p;
    }
  }

  Person._internal(this.name);
}

3.3. Setter and getter

By default, the properties defined by classes in dart can be accessed directly by the outside world.

But in some cases, we want to monitor thisClass propertiesThe process being accessed can be used at this timeSetter and getter

main(List<String> args) {
  Final d = dog ("yellow");
  d. SetColor = "black";
  print(d.getColor);
}

class Dog {
  String color;

  String get getColor {
    return color;
  }
  set setColor(String color) {
    this.color = color;
  }

  Dog(this.color);
}

3.4. Inheritance of class

One of the characteristics of object-oriented is inheritance. Inheritance is not onlyReduce our codeAlsoThe premise of polymorphism

Use of inheritance in dartExtends keyword, super is used in the subclass to access the parent class.

All member variables and methods in the parent class are inherited, except for construction methods.

main(List<String> args) {
  var p = new Person();
  p.age = 18;
  p.run();
  print(p.age);
}

class Animal {
  int age;

  run() {
    Print ('running ');
  }
}

class Person extends Animal {

}

Subclass canHas its own member variables,And canOverride the method of the parent class

class Person extends Animal {
  String name;

  @override
  run() {
    Print ('$name running');
  }
}

The construction method of the parent class can be called in the subclass to initialize some properties:

  • The construction method of the subclass will implicitly call theDefault construction method without parameters(a constructor with no parameters and the same name as the class).
  • If the parent class does notDefault construction method without parameters, the constructor of the subclass must pass thesuperExplicitly calls a constructor of the parent class.
class Animal {
  int age;

  Animal(this.age);

  run() {
    Print ('running ');
  }
}

class Person extends Animal {
  String name;

  Person(String name, int age) : name=name, super(age);

  @override
  run() {
    Print ('$name running');
  }

  @override
  String toString() {
    return 'name=$name, age=$age';
  }
}

3.5. Abstract class

We know that inheritance is the premise of polymorphism.

So there are many general definitionsCalling interfaceWe usually let the callerIncoming parent class, to achieve a more flexible way of calling through polymorphism.

However, the parent class itself may not need to implement some methods, so the methods defined in the parent class can be defined asAbstract method

What is?Abstract method? in dart, there is no concrete method (no method body), that is, abstract method.

  • Abstract methods must exist in abstract classes.
  • Abstract classes are usingabstractDeclared class.

In the following code, the shape class is an abstract class, which contains an abstract method

abstract class Shape {
  getArea();
}

class Circle extends Shape {
  double r;

  Circle(this.r);

  @override
  getArea() {
    return r * r * 3.14;
  }
}

class Reactangle extends Shape {
  double w;
  double h;

  Reactangle(this.w, this.h);

  @override
  getArea() {
    return w * h;
  }
}

matters needing attention:

  • Note 1:Abstract classes cannot be instantiated
  • Note two:Abstract methods in abstract classes must be implemented by subclasses. Methods in abstract classes can be implemented without being rewritten by subclasses

3.6. Implicit interface

Dart interface is special, there is no special keyword to declare the interface

By default, each class defined is equivalent to an interface declared by default, which can be implemented by other classes (because dart does not support multiple inheritance)

In development, we usually declare the classes used to implement for others as abstract classes:

abstract class Runner {
  run();
}

abstract class Flyer {
  fly();
}

class SuperMan implements Runner, Flyer {
  @override
  run() {
    Print ('superman running ');
  }

  @override
  fly() {
    Print ('superman is flying ');
  }
}

3.7. Mixin

When implementing a class through implements, all methods in the class mustBe reimplementedWhether this class has implemented the method or not.

But in some cases, a class may want to reuse the original implementation scheme of the previous class directly. How to do it?

  • Use inheritance? But dart only supports single inheritance, which means you can only reuse the implementation of one class.

Dart offers an alternative:Mix in

  • In addition to defining a class through class, you can also define a class through the mixin keyword.
  • Only the classes defined by mixin are used to be mixed by other classes, and mixed by with keyword.
main(List<String> args) {
  var superMan = SuperMain();
  superMan.run();
  superMan.fly();
}

mixin Runner {
  run() {
    Print ('running ');
  }
}

mixin Flyer {
  fly() {
    Print ('flying ');
  }
}

//The way of implements requires that the methods in it must be re implemented
// class SuperMan implements Runner, Flyer {}

class SuperMain with Runner, Flyer {

}

3.8. Class members and methods

Previously, the members and methods defined in the class belong to the object level. In development, we sometimes need to define the members and methods at the class level

In dart, we use the static keyword to define:

main(List<String> args) {
  var stu = Student();
  stu.name = 'why';
  stu.sno = 110;
  stu.study();

  Student. Time = '8 a.m.';
  //Stu.time = '9am'; in the wrong way, the instance object cannot access the class member
  Student.attendClass();
  //Stu. Attendclass(); wrong way to implement object complement to access class method
}

class Student {
  String name;
  int sno;

  static String time;

  study() {
    Print ('$name learning');
  }

  static attendClass() {
    Print ('Go to class');
  }
}

3.9. Enumeration type

Enumerations are also very common in development. Enumerations are also a special class, usually used to represent a fixed number ofconstant value

3.9.1. Definition of enumeration

Enumerations are defined using the enum keyword:

main(List<String> args) {
  print(Colors.red);
}

enum Colors {
  red,
  green,
  blue
}

3.9.2. Properties of enumeration

There are two common properties in enumeration types:

  • Index: the index used to represent each enumeration constant, starting from 0
  • Values: list containing the values of each enumeration
main(List<String> args) {
  print(Colors.red.index);
  print(Colors.green.index);
  print(Colors.blue.index);

  print(Colors.values);
}

enum Colors {
  red,
  green,
  blue
}

Note for enumeration types:

  • Note 1: you cannot subclass, mix, or implement enumerations.
  • Note 2: an enumeration cannot be explicitly instantiated

Four. Generic

4.1. Why generics?

For students with foundation, this part will not be explained

4.2. Generics of list and map

List in general:

//How to create a list
  var names1 = ['why', 'kobe', 'james', 111];
  print(names1.runtimeType); // List<Object>

  //Restriction type
  Var Names2 = < string > ['Why ',' Kobe ',' James', 111]; // the last error is reported
  List < string > names3 = ['Why ',' Kobe ',' James', 111]; // the last error is reported

Generics for map usage:

//How to create a map
  var infos1 = {1: 'one', 'name': 'why', 'age': 18}; 
  print(infos1.runtimeType); // _InternalLinkedHashMap<Object, Object>

  //Display type
  Map < string, string > infos2 = {'name': 'why', 'age': 18}; // 18 cannot be placed in value
  Var infos3 = < string, string > {'name': 'why', 'age': 18}; // 18 cannot be placed in value

4.3. Generics of class definition

If we need to define a class to store location information, but we are not sure whether the user wants to use int type, double type, or even a string, how to define it?

  • One is to use the object type, but it is very inconvenient to use later
  • Another option is to use generics

Definition of location class: object method

main(List<String> args) {
  Location l1 = Location(10, 20);
  print(l1.x.runtimeType); // Object
}

class Location {
  Object x;
  Object y;

  Location(this.x, this.y);
}

Definition of location class: generic approach

main(List<String> args) {
  Location l2 = Location<int>(10, 20);
  print(l2.x.runtimeType); // int 

  Location l3 = Location<String>('aaa', 'bbb');
  print(l3.x.runtimeType); // String
}
}

class Location<T> {
  T x;
  T y;

  Location(this.x, this.y);
}

What if we want the type to be num only?

main(List<String> args) {
  Location l2 = Location<int>(10, 20);
  print(l2.x.runtimeType);
    
  //Bad writing, type must inherit from num
  Location l3 = Location<String>('aaa', 'bbb');
  print(l3.x.runtimeType);
}

class Location<T extends num> {
  T x;
  T y;

  Location(this.x, this.y);
}

4.4. Definition of generic methods

Initially, dart only supported generics in classes. Later, a new syntax called generic methods allowed type parameters to be used in methods and functions.

main(List<String> args) {
  var names = ['why', 'kobe'];
  var first = getFirst(names);
  print('$first ${first.runtimeType}'); // why String
}

T getFirst<T>(List<T> ts) {
  return ts[0];
}

5、 Use of Libraries

In dart, you can import a library to use the functions it provides.

The use of library can improve the reusability of code, and can better combine code.

Any dart file in dart is a library, even if you don’t use keywordslibrarystatement

5.1. Import of Library

The import statement is used to import a library, followed by a URI in the form of string to specify the library to be referenced. The syntax is as follows:

Import 'URI where the library is located';

Common library URIs come in three different forms

  • From dart Standard Edition, such as dart: IO, dart: HTML, dart: math, dart: core (but this can be omitted)
//Dart: prefix represents DART's standard library, such as dart: IO, dart: HTML, dart: Math
import 'dart:io';
  • A library imported using a relative path, usually other dart files defined in your own project
//Of course, you can also refer to dart files with relative or absolute paths
import 'lib/student/student.dart';
  • Some libraries managed by the pub package management tool, including its own configuration and some third-party libraries, usually use the prefix package
//There are many powerful and practical libraries in the pub package management system. You can use the prefix package:
import 'package:flutter/material.dart';

Display and hide of contents in library files

If hopeImport only some content in the warehouseOr deliberatelyHide some content in the library, you can useshowandhideKeyword

  • Show keyword:Can display a member (mask others)
  • Hide keyword:You can hide a member (show others)
import 'lib/student/student.dart' show Student, Person;

import 'lib/student/student.dart' hide Person;

The content in the library conflicts with the name in the current file

When there are naming conflicts between libraries, you can use theAs keywordTo use a namespace

import 'lib/student/student.dart' as Stu;

Stu.Student s = new Stu.Student();

5.2. Definition of Library

Library keyword

Usually when defining a library, we can use the library keyword to give the library a name.

But at present, I find that the name of the library does not affect the import, because the import statement uses the string URI

library math;

Part keyword

When we used student.dart as a walkthrough, we just used the file as a library.

In development, if a library file is too large, it is not reasonable to save all the contents to a folder. We may want to split the library and use it at this timepartKeyword.

However, the government has not recommended this way:

  • https://dart.dev/guides/libra…

Dart (2)

mathUtils.dartfile

part of "utils.dart";

int sum(int num1, int num2) {
  return num1 + num2;
}

dateUtils.dartfile

part of "utils.dart";

String dateFormat(DateTime date) {
  return "2020-12-12";
}

utils.dartfile

part "mathUtils.dart";
part "dateUtils.dart";

test_libary.dartfile

import "lib/utils.dart";

main(List<String> args) {
  print(sum(10, 20));
  print(dateFormat(DateTime.now()));
}

Dart (2)

Export keyword

Officially not recommendedPart keyword, if the library is very large, how to manage it?

  • Use the export keyword to import each dart file as a library file

mathUtils.dartfile

int sum(int num1, int num2) {
  return num1 + num2;
}

dateUtils.dartfile

String dateFormat(DateTime date) {
  return "2020-12-12";
}

utils.dartfile

library utils;

export "mathUtils.dart";
export "dateUtils.dart";

test_libary.dartfile

import "lib/utils.dart";

main(List<String> args) {
  print(sum(10, 20));
  print(dateFormat(DateTime.now()));
}

Finally, you can also manage your own library through pub. I don’t think it’s very necessary in project development, so I won’t explain this method for the time being.

Note: all contents start with the official account. After that, Flutter will update other technical articles. TypeScript, React, Node, uniapp, mpvue, data structure and algorithm will also update some of their learning experiences. Welcome everyone’s attention.

Dart (2)

Recommended Today

Java security framework

The article is mainly divided into three parts1. The architecture and core components of spring security are as follows: (1) authentication; (2) authority interception; (3) database management; (4) authority caching; (5) custom decision making; and;2. To build and use the environment, the current popular spring boot is used to build the environment, and the actual […]