dart 构造函数
ClassName(...) //普通构造函数
普通构造函数
这就是我们普通的构造函数,其样子和其它语言几乎一样
class Point {
num x, y;
Point(num x, num y) {
// There's a better way to do this, stay tuned.
this.x = x;
this.y = y;
}
}
上例中只有两个成员变量,如果有10个,岂不是麻烦死?所以Dart有语法糖给你哦:
class Point {
num x, y;
// Syntactic sugar for setting x and y
// before the constructor body runs.
Point(this.x, this.y);
}
它可以将x,y的赋值变得简单一些,就不用写构造函数的方法体了,记得括号后用分号哦。
Classname.identifier(...) //命名构造函数
命名构造函数
class Point {
num x, y;
Point(this.x, this.y);
// 命名构造函数,新增代码
Point.origin() {
x = 0;
y = 0;
}
}
请记住,命名构造函数不可继承,如果子类想要有 和父类一样的命名构造函数,那就写个同名的(通常也会在子类的命名构造函数里,调用父类的同名命名构造函数)
const ClassName(...) //常量构造函数
常量构造函数总结如下几点:
常量构造函数需以const关键字修饰
const构造函数必须用于成员变量都是final的类
构建常量实例必须使用定义的常量构造函数
如果实例化时不加const修饰符,即使调用的是常量构造函数,实例化的对象也不是常量实例
下面结合实例,对以上几点加以说明
正确的常量构造函数定义
根据以上的总结,定义一个Point类,包含一个常量构造函数,注意其成员变量都是final类型,且构造函数用const修饰
class Point {
final int x;
final int y;
const Point(this.x, this.y);
}
常量构造函数需以const关键字修饰
如下代码定义一个const对象,但是调用的构造方法不是const修饰的,则会报The constructor being called isn't a const constructor.错误
void main() {
const point = Point(1, 2); // 报错
}
class Point {
final int x;
final int y;
Point(this.x, this.y);
}
const构造函数必须用于成员变量都是final的类
如下代码中成员变量x为非final,会报Can't define a const constructor for a class with non-final fields.错误
class Point {
int x;
final int y;
const Point(this.x, this.y);
}
构建常量实例必须使用定义的常量构造函数
如下代码,定义一个const对象,但是调用的却是非常量构造函数,会报The constructor being called isn't a const constructor.错误
void main() {
var point = const Point(1, 2); // 报错
print(point.toString());
}
class Point {
int x;
int y;
Point(this.x, this.y); // 非const构造函数
String toString() {
return 'Point(${x}, ${y})';
}
}
如果实例化时不加const修饰符,即使调用的是常量构造函数,实例化的对象也不是常量实例
如下代码,用常量构造函数构造一个对象,但是未用const修饰,那么该对象就不是const常量,其值可以再改变
void main() {
var point = Point(1, 2); // 调用常量构造函数,但是未定义成常量
print(point.toString());
point = Point(10, 20); // 可以重新赋值,说明定义的变量为非常量
print(point.toString());
}
class Point {
final int x;
final int y;
const Point(this.x, this.y);
String toString() {
return 'Point(${x}, ${y})';
}
}
factroy ClassName(...) //工厂构造函数
工厂构造函数的定义
工厂构造函数是一种构造函数,与普通构造函数不同,工厂函数不会自动生成实例,而是通过代码来决定返回的实例对象.
工厂构造函数的关键字为factory,下面我们用工厂构造函数写一个只能创造一个实例的类.
class A{
String name;
static A cache;
factory A([String name='A']){
if(A.cache===null){
A.cache=new A.newObject(name);
}
return A.cache;
}
A.newObject(this.name);
}
void main(){
A a=new A('HelloWorld');
print(a.name);
A b=new A('HelloDart');
print(b.name);
print(a===b);
}
A类具有一个名为cache的静态成员,它将缓存A类的第一个实例.
在工厂构造函数A中,首先判断A.cache是否已经存在实例(即判断是否是第一次实例化),如果存在则返回缓存的实例,不存在则新建一个实例并缓存.
A.newObject是一个命名构造函数,用于创建实例.
运行这段代码,会输出
HelloWorld
HelloWorld
true
其中字符串”HelloWorld”是第一个实例的name成员,在声明变量b时改用了”HelloDart”,但返回的实例的name成员仍然是”HelloWorld”.
再用===运算符判断一下它们是否属于同一个对象,结果为true,变量a和b指向的是同一个对象.
3.8.2 工厂构造函数的特性
工厂构造函数类似于static静态成员,无法访问this指针,所以在工厂构造函数中能处理的任务较为有限.
使用工厂构造函数时往往需要定义一个命名构造函数用来生产实例.
注意点
初始化列表
初始化列表的执行顺序,在整个构造函数的最前面,它除了可以调用父类的构造函数,还可以在构造函数方法体之前,初始化一些成员变量。
// Initializer list sets instance variables before
// the constructor body runs.
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson(): ($x, $y)');
}
尤其是初始化那些final修饰的成员变量时,初始化列表很有用,因为在方法体中,不能给final修饰的成员变量赋值,因为在执行方法体的时候,final修饰的成员变量已经不能变了。这个地方很多人犯错。
import 'dart:math';
class Point {
final num x;
final num y;
final num distanceFromOrigin;
Point(x, y)
: x = x,
y = y,
distanceFromOrigin = sqrt(x * x + y * y);
}
main() {
var p = new Point(2, 3);
print(p.distanceFromOrigin);
}
gtest mockcpp 构造函数 dart 构造函数
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Dart构造函数
Dart构造函数1.Dart构造函数的4种格式:1.1.默认构造函数1.2.普通构造函数1.3.命名构造函数1.4.常量构造
Dart 构造函数 父类 json -
dart系列之:dart类中的构造函数
简介 dart作为一种面向对象的语言,class是必不可少的。dart中所有的class,除了Null都继承自Ob
dart flutter 程序那些事 构造函数 json -
构造函数与缺省构造函数
在C++中,结构体与类是相似的,他们可以互相进行继承操作
构造函数 初始化 赋值 -
swift 构造函数 构造函数=default
使用=default生成默认构造函数
swift 构造函数 构造函数 初始化 编译器