Create a Dart class

Simple to use

class Bicycle { int cadence; int speed; int gear; // Constructor: No method body in Dart is legalized Bicycle(this.cadence, this.speed, this.gear); Bicycle(int cadence, int speed, int gear) {this.cadence = cadence; this.speed = speed; this.gear = gear; }*/} main() {// instantiate and print var bike = new Bicycle(2, 0, 1); Bike = Bicycle(2, 0, 1); print(bike); }Copy the code

Instance of ‘Bicycle’

Description:

  • Main () main method. If you need to access arguments passed from the command line, use main(List args).
  • Variable – free access control keywords are public by default.
  • 2 character indentation, formatted using Dartfmt, found in the toolbar under Code.
  • In instantiation, new becomes optional
  • Make sure the value does not change and use final instead of var.

Optimize output information

Add the toString() method anywhere in Bicycle

@override String toString() => 'Bicycle: $speed MPH ';Copy the code

Result: Bicycle: 0 MPH

Add a read-only private variable and add getter methods

The code is as follows:

class Bicycle { int cadence; int _speed=0; //getter method int get speed =>_speed; int gear; Bicycle(this.cadence,this.gear); void applyBrake(int decrement) { _speed -= decrement; } void speedUp(int increment) { _speed += increment; } @override String toString() => 'Bicycle: $speed mph'; } main() {var bike = Bicycle(2,1); print(bike); }Copy the code

Description:

  • Add underscore _ to mark private.
  • Uninitialized variables (even numeric ones) have a value of NULL.
  • Dart provides access methods for all exposed variables and does not need to be redefined unless it is only readable, writable, or in some cases requires evaluation in getter methods or some worthwhile update in setter methods.
  • Instance variables can be accessed directly by bike. Gear or bike. Cadence.

Overload the constructor with optional arguments

Java uses overloaded constructors, that is, overloaded constructors with the same names as the original constructors, but with slightly different numbers or types of arguments to the method. Dart does not support constructor overloading, opting instead to use optional arguments. The implementation code is as follows:

import 'dart:math'; class Rectangle { Point origin; int width; int height; //this.origin, this.width, and this.height use the handy methods provided by Dart to assign directly to instance variables in a class. //this.origin, this.width, and this.height are nested within closed curly braces ({}) to indicate that they are optional named arguments. //this.origin = const Point(0,0); //this.origin = const Point(0,0); Rectangle({this.origin = const Point(0, 0), this.width = 0, this.height = 0}); @override String toString() => 'Origin: (${origin.x}, ${origin.y}), width: $width, height: $height'; Print (Rectangle(Origin: const Point(10, 20), width: 100, height: 200)); print(Rectangle(origin: const Point(10, 10))); print(Rectangle(width: 200)); print(Rectangle()); }Copy the code

Running results:

Origin: (10, 20), width: 100, height: 200
Origin: (10, 10), width: 0, height: 0
Origin: (0, 0), width: 200, height: 0
Origin: (0, 0), width: 0, height: 0

Copy the code

Dart saves code and is simpler to write than Java because of the Dart language features.

Create factory method

The factory class is a widely used design pattern that has many advantages over directly instantiating classes, such as hiding the details of the instantiation, providing the ability to be configured for other classes, and returning an existing object directly rather than a new one. Factory class methods can be implemented either by creating a top-level method or by creating a constructor for the factory pattern.

Simple implementation example

The code is as follows:

import 'dart:math';

abstract class Shape {
  num get area;
}

class Circle implements Shape {
  final num radius;
  Circle(this.radius);
  num get area => pi * pow(radius, 2);
}

class Square implements Shape {
  final num side;
  Square(this.side);
  num get area => pow(side, 2);
}

main() {
  final circle = Circle(2);
  final square = Square(2);
  print(circle.area);
  print(square.area);
}

Copy the code

Output result:

12.566370614359172
4

Copy the code

Description:

  • Dart supports abstract classes
  • Multiple classes can be defined in a single text
  • Core library math. The dart

Create a top-level method

Created outside all classes

Shape shapeFactory(String type){
  if(type=='circle')return Circle(2);
  if(type=='square')return Square(2);
  throw 'Can't creat $type.';
}
Copy the code

Modify the first two lines of main()

final circle = shapeFactory('circle');
final square = shapeFactory('square');
Copy the code

The result is the same, but returns an existing object instead of a new one. Other notes:

  • When an exception occurs, DartPad directly throws Uncaught, and you can wrap the code in a try-catch statement to catch the exception.
  • If a string contains single quotes, then you need to add an escape character (‘Can’t create $type.’) before the single quotes inside the string if the string is declared in single quotes, but not if the string is alive with double quotes (“Can’t create $type.”).

Create a constructor for the factory pattern

The complete code is as follows:

import 'dart:math';

abstract class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle(2);
    if (type == 'square') return Square(2);
    throw 'Can't creat $type.';
  }
  num get area;
}

class Circle implements Shape {
  final num radius;
  Circle(this.radius);
  num get area => pi * pow(radius, 2);
}

class Square implements Shape {
  final num side;
  Square(this.side);
  num get area => pow(side, 2);
}

main() {
  final circle = Shape('circle');
  final square = Shape('square');
  print(circle.area);
  print(square.area);
}
Copy the code

Add the factory constructor to Shape and modify the first two lines of main(). The above code is identical to the shapeFactory() method you created earlier.

Interface implementation

The Dart language does not provide the interface keyword, but each class implicitly defines an interface.

The code is as follows:

class Circle implements Shape { final num radius; Circle(this.radius); num get area => pi * pow(radius, 2); } class CircleMock implements Circle{ num area; // Implement Shape interface num RADIUS; // implement the Circle interface}Copy the code

Functional programming in Dart

What’s the use of the function?

  • Pass the function as an argument
  • Assign functions directly to variables
  • Destruct a function, call it by passing it only a few arguments, and make it return a function to handle the rest
  • Create an anonymous function that can be treated as a constant (also known as a lambda expression)

Imperative programming:

String scream(int length) => "A${'a' * length}h!" ; {final values = [1, 2, 3, 5, 10, 50]; for (var length in values) { print(scream(length)); }}Copy the code

Functional programming: change the values in the for loop to values.map(scream).foreach (print);

Running results:

Aah!
Aaah!
Aaaah!
Aaaaaah!
Aaaaaaaaaaah!
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah!
Copy the code

The List and Iterable in the Collection library support fold, WHERE, Join, skip and other functional methods. Dart also supports Map and Set types.

Skip (1).take(3).map(scream).foreach (print);

  • Skip (1) ignores the first value and take(3) gets the next three values

Running results:

Aaah!
Aaaah!
Aaaaaah!
Copy the code