最多见的构造函数形式,即生成构造函数,建立一个类的新实例: class Point { num x, y; //Dart中int和double是num的子类 //this引用当前类对象 Point(num x, num y) { this.x = x; this.y = y; } } 使用语法糖的时候能够这样定义: class Point { num x, y; //用于设置x和y的语法糖 //在构造函数体运行以前 Point(this.x, this.y); @override String toString() { return ("x: $x, y: $y"); } } //print(new Point(100, 200)); -> 打印 x: 100, y: 200 默认构造函数 若是未声明构造函数,则会提供默认构造函数。 默认构造函数没有参数,并在调用父类无参数构造函数。 class Parent{ Parent(){ print('In Parent\'s constructor.'); } } class Child extends Parent{ Child(){ print('In Child\'s constructor.'); } } //new Child(); -> 打印 In Parent's constructor. In Child's constructor. 构造函数不能继承 子类不能继承其父类构造函数,一个没有声明构造函数的子类只有默认(无参数,无名称)构造函数 命名构造函数 当咱们须要定义一个有特别含义的构造函数的时候,能够经过构造函数.XXX来命名构造函数 class Point{ num x; num y; Point(this.x, this.y); //建立一个坐标原点类 Point.origin(){ this.x = 0; this.y = 0; } //建立一个坐标为(100, 100)的类 Point.coordinate100(){ this.x = 100; this.y = 100; } @override String toString() { return ("x: $x, y: $y"); } } 调用父类构造函数 默认状况下,子类中的构造函数调用父类的未命名无参数构造函数。 父类的构造函数在子类构造函数体的开头被调用。 若是还使用初始化了列表,则会在调用父类构造函数以前执行。 执行顺序以下: 初始化列表 父类的无参数构造函数 子类的无参数构造函数 若是父类没有未命名的无参数构造函数,则必须手动调用父类中的一个构造函数。 在子类的构造函数体以后用冒号(:)指定父类构造函数 例1:默认先调用父类的无参数构造函数 class Parent{ Parent(){ print('In Parent\'s constructor.'); } } class Child extends Parent{ Child(num x, num y) { print('In Child\'s constructor.'); } } //new Child(100, 100); -> 打印 //In Parent's constructor. //In Child's constructor. 例2:手动调用父类其余构造函数 class Parent{ num x; num y; Parent(this.x, this.y){ print('In Parent\'s constructor.'); } } class Child extends Parent{ Child(num x, num y) : super(x, y){ print('In Child\'s constructor.'); } } //new Child(100, 100); -> 打印 //In Parent's constructor. //In Child's constructor. 关于初始化列表: 调用父类构造函数以前,能够在构造函数体执行以前初始化示例变量,用逗号分隔,该过程叫初始化列表。 class Parent{ num x; num y; num sum; Parent(num px, num py) : x = px, y = py, sum = px + py{ print("x: $x, y: $y, sum: $sum"); print('In Parent\'s constructor.'); } } class Child extends Parent{ Child(num x, num y) : super(x, y){ print('In Child\'s constructor.'); } } // new Child(100, 100); -> 打印 //x: 100, y: 100, sum: 200 //In Parent's constructor. //In Child's constructor. 重定向构造函数 有时构造函数须要重定向到同一个类中的另外一个构造函数,在冒号后面用this: class Point { num x, y; //类的主构造函数 Point(this.x, this.y); //重定向到主构造函数 Point.alongXAxis(num x) : this(x, 0); } 常量构造函数 若是你的类须要成为永远不会更改的对象,则可使这些对象成为编译时常量。 定义const构造函数要确保全部实例变量都是final。 class Point { final num x; final num y; static final Point2 origin = const Point2(0, 0); //const关键字放在构造函数名称以前,且不能有函数体 const Point2(this.x, this.y); } 没有定义final时提示: const-construcot.png 使用函数体时提示: const-construcot.png 工厂构造函数 在实现不用老是建立新的类对象的时候,可使用factory关键字。 例如,工厂构造函数可能从缓存中返回实例,或者它可能返回子类型的实例: class Logger { final String name; bool mute = false; //工厂构造函数没法访问this,因此这里要用static //维护一个缓存的Map对象, static final Map<String, Logger> _cache = <String, Logger>{}; //调用该构造函数的时候,会从Map中取出对象 factory Logger(String name) { if (_cache.containsKey(name)) { return _cache[name]; } else { final logger = Logger._internal(name); _cache[name] = logger; return logger; } } Logger._internal(this.name); void log(String msg) { if (!mute) print(msg); } } //调用 var logger = Logger('UI'); logger.log('Button clicked');