最常见的构造函数形式,即生成构造函数,创建一个类的新实例: 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‘);
原文地址:https://www.cnblogs.com/Free-Thinker/p/10838403.html
时间: 2024-10-07 05:29:42