Introduction

Dart is an object-oriented language, and class is essential. All classes in dart, except Null, inherit from Object class. If you want to use the class in dart, you must construct an instance of the class. In dart, there are two ways to construct a class. Let's take a look.

Traditional constructor

Like JAVA, dart can use the same function as the class name as its constructor. This is also the first way to create a constructor in many programming languages. Let’s take the Student class as an example to see how the constructor in dart is Kind of:

class Student {
  int age = 0;
  int id = 0;

  Point(int age, int id) {
    this.age = age;
    this.id = id;
  }
}

The above this represents an instance of the current class. For dart, this can be ignored, but in the above example, because the name of the class variable is the same as the name of the parameter passed in the constructor, it needs to be added this to distinguish.

Although the above code is very simple, there is still too much content to write. The following is an abbreviation in dart:

class Student {
  int age = 0;
  int id = 0;

  Student(this.age, this.id);
}

Of course, you can also not specify a constructor, in which case dart will create a default constructor with no parameters for you.

Named constructor

The difference between dart and other languages is that you can also use named constructors. The format of the named constructor is ClassName.identifier, as shown below:


class Student {
  int age = 0;
  int id = 0;

  Student(this.age, this.id);

    Student.fromJson(Map data) {
    print('in Student');
  }
}

Student.fromJson above is a named constructor. You can use this constructor to generate a Student object from Map, a bit like a factory method in java.

The execution order of the constructor

We know that classes in dart can be inherited, so for subclasses in dart, what is the execution order of their constructors?

If you don't specify a constructor for the dart class, then dart will automatically generate a parameterless constructor for the class. If the class is a subclass, it will automatically call the parent class's parameterless constructor.

So for the constructor of the corresponding subclass, there are three steps when initializing:

  1. Call initialization list
  2. Call the constructor of the parent class
  3. Call your own constructor

In step 2, if the parent class does not have a default no-argument constructor, you need to manually specify the constructor of the specific parent class. How to call it? It can be used directly after the constructor of the subclass: the operator is connected to the constructor of the parent class, as shown below:

class Student {
  String? firstName;
  
  Student.fromJson(Map data) {
    print('in Student');
  }
}

class Jone extends Student {
  
  Jone.fromJson(Map data) : super.fromJson(data) {
    print('in Jone');
  }
}

After understanding the constructor of the parent class, let's take a look at what is an initialization list?

The initialization list is the code that is executed before the constructor is executed. It is the same as calling the constructor of the parent class. It also uses the operator, as shown below:

Point.fromJson(Map<String, double> json)
    : x = json['x']!,
      y = json['y']! {
  print('In Point.fromJson(): ($x, $y)');
}

Redirect constructor

If a constructor needs to call another constructor without any changes in itself, you can use the redirection constructor. The redirection constructor also uses the: operator, followed by another constructor:

class Point {
  double x, y;

  // 主构造函数
  Point(this.x, this.y);

  // 重定向构造函数
  Point.alongXAxis(double x) : this(x, 0);
}

Constant constructor

If the properties in the object will not change after creation, you can use the Constant constructor, that is, add the const modifier in front of the constructor, and all initialized properties must be finalized:

class ImmutablePoint {
  static const ImmutablePoint origin = ImmutablePoint(0, 0);

  final double x, y;

  const ImmutablePoint(this.x, this.y);
}

Factory constructor

By default, the constructor in the dart class returns a new instance of the class, but we may make some choices about the returned object in actual applications, such as returning an existing object from the cache, or returning the class Specific implementation subclass.

In order to achieve such a function, there is a Factory keyword in dart, and the constructor that uses the Factory is called the factory constructor.

class Student {
  final String name;

  static final Map<String, Student> _studentMap =
  <String, Student>{};

  factory Student(String name) {
    return _studentMap.putIfAbsent(
        name, () => Student._newStudent(name));
  }

  factory Student.fromJson(Map<String, Object> json) {
    return Student(json['name'].toString());
  }

  Student._newStudent(this.name);
}
Note that there can only be one unnamed constructor in dart. For named functions, the name cannot be repeated, otherwise the exception The default constructor is already defined will be reported.

In the above code, factory Student is an unnamed constructor, and factory Student.fromJson is a named constructor.

So if you add an unnamed constructor to Student, as follows:

Student(this.name);

It will report an error.

So the question is, what is the difference between a factory constructor and a normal constructor?

The biggest difference between them is that the normal constructor has no return value, while the factory constructor requires a return value.

Summarize

The above is the various constructors in dart, and the issues that need to be paid attention to during use.

This article has been included in http://www.flydean.com/06-dart-class/

The most popular interpretation, the most profound dry goods, the most concise tutorial, and many tips you don't know are waiting for you to discover!

Welcome to pay attention to my official account: "Program those things", know technology, know you better!


flydean
890 声望433 粉丝

欢迎访问我的个人网站:www.flydean.com