This is the sixth day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

class

All objects in Dart are instances of a class that extends from the Object class.

The constructor

import 'dart:math';

/ / define the class
class Point {
  num x = 0, y = 0;

  // Point(this.x, this.y); / / the constructor

  / / or
  Point(x, y) {
    this.x = x;
    this.y = y;
    print('This is a constructor that fires on instantiation');
  }

  // Instance method
  num distanceTo(Point other) {
    var dx = x - other.x;
    var dy = y - other.y;
    return sqrt(dx * dx + dy * dy);
  }
}

main() {
  // Call the class constructor. New can be omitted
  Point p1 = new Point(1.2); // This is the constructor, which is triggered on instantiation
  Point p2 = Point(3.4); // This is the constructor, which is triggered on instantiation
  // Call the class method
  print(p1.distanceTo(p2)); / / 2.8284271247461903
}
Copy the code

Due to the nature of Dart 2.12, writing the constructor like this will return an error:

class Point {
  num x, y;
  Point(x, y) {  // Non-null instance field 'x' must be initialized
      			// Try adding an initializer, or add a field initializer to the constructor, or mark it
    this.x = x;
    this.y = y; }}Copy the code

Dart doesn’t know if you assigned variables to x and y because of space safety. Dart-non-nullable instance field must be initialized – Stack Overflow dart-non-nullable instance field must be initialized – Stack Overflow

One solution:

class Point {
  num? x, y;
  Point(x, y) {
    this.x = x;
    this.y = y; }}Copy the code

num? Represents a nullable type, indicating that the value of a variable can be null.

You can use named constructors to implement multiple constructors for a class, or use named constructors to semantic your code, as was the datetime.now () constructor previously used.

Use the redirection constructor to call other constructors with colons.

class Point {
  num? x;
  num? y;

  Point.initX(y) { // Name the constructor
    this.x = 2;
    this.y = y;
  }

  Point.redirctor(num x) : this(x, 0); // Redirect the constructor
}

main() {
  Point p1 = Point.initX(2); 
  print('${p1.x}.${p1.y}'); / / 2, 2
  Point p2 = Point.redirctor(1); 
  print('${p2.x}.${p2.y}'); / / 1, 0
}
Copy the code

More and more code leads to less and less maintenance, so we need to separate classes into files and import libraries using imports where needed.

// lib\Point.dart
class Point {
  num x = 0, y = 0;
  Point(this.x, this.y); 
}

// main.dart
import 'lib/Point.dart';
main(){
	/ /...
}
Copy the code

Class and member visibility

Visibility in Dart is measured in library, and each Dart file is a library.

Use _ to represent a private property of a property or method, the Java equivalent of privite.

class Point {
  num _x = 0, _y = 0;
  Point(this.x, this.y); 
}
Copy the code

The private attribute takes effect only when it is detached into a file.

Getter and setter

Each variable has its default getter and setter methods, and final variables are only readable, with only getter methods.

In Dart, methods cannot be overloaded.

class Rect {
  late num width, height;
  Rect(this.width, this.height);
  area() {
    return this.width * this.height;
  }

  // getter
  get area1 {
    return this.width * this.height;
  }

  // setter
  set height2(value) {
    this.height = value;
  }
}

main() {
  Rect r1 = Rect(1.2);
  print(r1.area()); / / 2
  print(r1.area1); / / 2
  r1.height2 = 3;
  print(r1.area1); / / 3
}
Copy the code

Initialization list

Initializing lists is done before instantiation:

class Rect {
  late num width, height;
  // Rect(this.width, this.height); Cannot be used simultaneously
  Rect()
      : width = 2,
        height = 3 {
    print('in class');
    print(this.width * this.height);
  }
}

main() {
  Rect r1 = Rect();
  print('in main');
}

// Output the result
// in class
// in main
/ / 6
Copy the code

Static Static member

Static variables and methods can be accessed through a class, not an instance of a class.

class Person {
  static String name = 'Jackie';
  static void show() {
    print(name);
  }
}

main() {
  print(Person.name); //Jackie
  Person.show(a);// Jackie
}
Copy the code

Static methods cannot access non-static members, and non-static methods can access static members.

class Person {
  static String name = 'Jackie';
  static show() {
    print(name);
  }
  showInfo() {
    print(name);
    show(a); } } main() { Person p = Person(); p.showInfo();// Jackie Jackie
}
Copy the code

inheritance

  1. A subclass inherits its parent class using the extends keyword;

  2. A subclass inherits visible attributes and methods from its parent class except for constructors.

  3. A subclass can duplicate the methods of its parent class.

class Person {
  late String name;
  late int age;
  Person(this.name, this.age);
  work() {
    print('$name is working.'); }}class Web extends Person {
  late String sex;
  // Subclass constructor
  Web(String name, int age, String sex) : super(name, age) {
    this.sex = sex;
  }
  // Subclasses can override methods of their parent class
  @override // Override the parent class method, select write
  work() {
    print('$name is working 996.');
  }
}

main() {
  Web w = Web('Tom'.20.'male');
  print(w.sex); // male
  w.work(); // Tom is working 996.
}
Copy the code

An abstract class

Dart abstract classes are used to define standards, and subclasses can inherit abstract classes or implement abstract class interfaces.

  1. The abstract class passesabstractKeyword to define.
  2. Methods that have no method body in Dart are called abstract methods.
  3. If a subclass inherits an abstract class, it must implement its abstract methods.
  4. If you use an abstract class as an interface implementation, you must implement all properties and methods defined in the abstract class.
  5. Abstract classes cannot be instantiated, only subclasses that inherit from them can.

The difference between extends and implements:

  1. If we want to reuse methods from an abstract class, and we want to constrain our own class with an abstract method, we use itextendsInherit abstract classes.
  2. If you’re just using abstract classes as a standardimplementsImplement abstract classes.
abstract class Person {
  late String name;
  late int age;
  Person(this.name, this.age);
  work(); // Abstract methods
}

class Employee extends Person {
  Employee(String name, int age) : super(name, age);
  @override
  work() {
    print('$name is working 996.'); }}class Employee2 extends Person {
  Employee2(String name, int age) : super(name, age);
  @override
  work() {
    print('$name is working 669.');
  }
}

main() {
  Person e = Employee('Tom'.20);
  e.work(); // Tom is working 996.
  // Person p = Person(); // The abstract class cannot be instantiated
  Person e2 = Employee2('Jerry'.20);
  e2.work(); // Jerry is working 669.
}
Copy the code

polymorphism

Is a reference that assigns an instance of a subclass to a parent class, allowing a pointer of a subclass type to be assigned to a pointer of a parent class type. The same function call may have different execution effects.

Polymorphism is when a parent class defines a method and lets its subclasses implement it, each of which behaves differently.

In the example above, both the Employee and Employee2 classes are polymorphic.

interface

Dart also has interfaces, but they are different from Java.

Dart interfaces do not have the interface keyword. Instead, ordinary or abstract classes can be implemented as interfaces using the implements keyword.

If the class is ordinary, all the methods of attributes in ordinary and abstract classes need to be overridden. Because abstract classes can define abstract methods and ordinary classes cannot, it is recommended to use abstract classes to define interfaces.

abstract class Db {
  late String uri;
  add(String data);
}

class Mysql implements Db {
  @override
  late String uri;

  Mysql(this.uri);

  @override
  add(String data) {
    print('This is Mysql. ' + '$data');
  }
}

main() {
  Mysql m = Mysql('xxx');
  m.add('123');
}
Copy the code

Interfaces are separated into different files:

// lib\Db.dart
abstract class Db {... }// lib\Mysql.dart
import 'lib/Db.dart';
class Mysql implements Db {... }// main.dart
import 'lib/Mysql.dart'; main() {... }Copy the code

A class can implement multiple interfaces

class C implements A.B {
    // A, B interface all properties and methods
}
Copy the code

Mixins

Class does not implement multiple inheritance. Mixins, unlike inheritance and interfaces, can implement functions similar to multiple inheritance:

class C extends A.B {} / / an error
class C with A.B {... }/ /)
Copy the code
  1. Classes that are Mixins can only inherit from Object, not from other classes.
  2. Classes that are Mixins cannot have constructors.
  3. A class can Mixins multiple Mixins classes.
  4. Mixins are far from being an inheritance or an interface, but rather an entirely new feature.
class A {... }class B extends A {... }class C {... }class D with B.c {... }/ / an error
class D extends A with B.C {... }/ /)
Copy the code

The last class overwrites the previous class:

class C with A.B {... }// B's method overwrites A
class D extends A with B.C {... }// Method B will cover A, method C will cover A and B
Copy the code