默认构造函数(无参)
不声明任何构造函数,创建的class会初始化一个默认的构造函数。
class Person {//里面包含了一个默认的构造函数 Person(){}}
当声明了构造函数,也就没有默认的构造函数了。如果声明了一个私有的构造函数,那就为创造单例提供了路子。
Dart里面的构造方法写法多样:
传统构造函数(类比java中的带参数的构造方法)
通过构造函数对变量完成初始化, 下面这种写法和Java语法近乎一样
class Person {String name;int age;Person(String name, int age) {this.name = name;this.age = age;}}
和Java不一样的是,还可以这样写:
class Person {String name;int age;//貌似这种初始化变量的写法才是Dart纯血Person (this.name, this.age);}
这种语法糖写法效果和上面一样,但是需要注意的是,Dart不支持无名称(java也没有这个概念)的构造函数重载。
要想实现类似重载重载的效果,Dart提供了命名构造函数。
命名构造函数
Java里面没有这玩意,他的语法是(类名.方法名), 要实现上述带参数的无名称构造方法,可以这样写:
class Person {String name;int age;Person.fromNameAndAge(this.name, this.age) : assert(age > 0) {//貌似这种初始化变量的写法才是Dart纯血}}
这种方法有这样几个坑:
- 对类变量的初始化,只能放在命名里面,也就是
fromNameAndAge(this.name, this.age),不能放在方法体; - 在命名构造函数右边,也就是冒号右边,跟了一串表达式,在Dart里面叫初始化列表;
初始化列表可以做这些(不一定全):
- 调用父类的命名构造方法
class Person {String name;int age;Person.fromNameAndAge(this.name, this.age) : assert(age > 0) {// parent named constructor}}class Tom extends Person {Tom.fromNameAndAge (super.name, super.age) : super.fromNameAndAge();}
- 初始化变量
class Point {int x;int y;Point.fromMap(Map<String, int> data) : x = data['x']!, y = data['y']! {//}}
- 重定向构造函数
重定向构造函数
这个在Java里面是不是类似重载?,emmm和Java相比还是有点新花样,思考一下,这样玩的优点是什么,还是只是语言新个性。
class Point {int x;int y;Point(this.x, this.y);//重定向过去就没有自己的方法体了Point.fromY(int y) : this(0, y);}
工厂构造函数
这个是不是已经超出了构造函数的队伍,但是需要深刻注意的是,构造函数返回的是该类的一个实例,这个实例可能是cache中的,也可能是新创建的。如何自定义的选择,使用工厂的这种模式,提供了算是Dart语言里面不算新花样的语言特性写法。
Dart提供了一个关键字factory,使用该关键字标记的函数叫做工厂构造函数,这个关键字可以放在无名或者有名字的构造函数上。
class Teacher {final String name;static final Map<String, Teacher> _teachers = <String, Teacher>{};factory Teacher(String name) {return _teachers.putIfAbsent(name, () => Teacher._newTeacher(name));}factory Teacher.fromJson(Map<String, Object> json) {return Teacher(json['name'].toString());}Teacher._newTeacher(this.name);}
加上了这个factory关键字后,区别于不加,他多了一个return,强行指定了返回的对象是哪个。
其实,也很简单!,But 工厂构造函数不能使用this
常量构造函数
class Point {static const int x = 0;final int y;const Point(this.y);const Point.fromY(int y) : this(y);}main() {Point point = new Point(0);Point point1 = const Point(0);Point point2 = const Point.fromY(0);Point point3 = const Point.fromY(1);print(point.hashCode);print(point1.hashCode);print(point2.hashCode);print(point3.hashCode);}---print---618489939991380737991380737342902289
按照某些网上大佬所言:
- const构造函数实际创建一个编译时常量对象
- 将“ new”与const构造函数一起使用,它仍然会创建一个对象,但是它将只是一个普通的新对象,而不是编译时常量值。
其它
构造函数初始化顺序
- 调用初始化列表
所思:为什么叫初始化列表呢?Point(this.y)是不是Point(y):y=y的语法糖? - 调用父类的构造函数
- 调用自己的构造函数
