dart构造函数解析
一 构造函数格式
ClassName()默认构造函数ClassName(…)普通构造函数(无名或无参)ClassName.identifier()命名构造函数(有参或无参)const ClassName(…)常量构造函数factory ClassName(…)工厂构造函数
二 构造函数定义和使用
2.1 默认构造函数
如果定义了一个类,在没有自定义其他构造函数的前提下,那么该类会有一个默认的构造函数,并且该函数没有名称也没有参数。
tips: 如果自定义了任何形式的构造函数,那么不会生成默认构造函数。
class Animal {double weight;double height;
}void main() {Animal animal = Animal(); // 调用默认构造函数animal.height = 180;animal.weight = 100;
}
2.2 普通构造函数
普通构造函数也没有函数名,可以定义参数或者无参数。
tips: 显式定义的无参普通构造函数和默认的构造函数形式一样。这里主要在继承时需要注意一下,下面的继承段落会阐述。
使用如下:
class Animal {double weight;double height;/// 定义普通构造函数Animal(double weight, double height) {this.weight = weight;this.height = height;}
}void main() {Animal animal = Animal(100, 180);
}
如果类有多个成员变量,那么使用 this.ivar = value的形式显得很繁琐,所以dart提供了语法糖,使用如下:
class Animal {double weight;double height;Animal(this.weight, this.height);
}void main() {Animal animal = Animal(100, 180);
}
2.3 命名构造函数
指定函数名称,然后可以添加参数或者无参数,也可以使用上述的语法糖,使用如下:
class Animal {double weight;double height;Animal.initial(this.weight, this.height);
}void main() {Animal animal = Animal.initial(100, 180);
}
2.4 常量构造函数
如果你希望你的实例对象创建出来后是不可改变的,那么可以定一个常量构造函数,在编译期就创建这个常量实例。
需要注意的点:
- 全部的成员变量必须是
final修饰的。 - 构造函数前使用
const进行修饰。
使用如下:
:为了确保创建的常量实例不可变,在调用时可以使用const进行修饰。
class Animal {final double weight;final double height;/// 使用const进行修饰const Animal(this.weight, this.height);
}void main() {const Animal animal = Animal(100, 180);
}
2.5 工厂构造函数
工厂构造函数的定义为每一次调用构造函数时,并不是都新建一个实例对象。
常用场景:
- 返回已经存在的对象。
- 创建单例。
- 用于返回指定的子类对象。
1.dart官方文档中的举例:
class Logger {final String name;bool mute = false;// _cache is library-private, thanks to// the _ in front of its name.static final Map<String, Logger> _cache =<String, Logger>{};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);}
}main() {var logger = Logger('UI');logger.log('Button clicked');
}
工厂构造函数根据传入的name为key,从_cache中寻找,如果有对应_key,则返回对应的logger对象。如果没有的话,则调用私有命名构造函数 Logger_internal(this.name)。
2.用于单例的创建
使用如下:
class Animal {Animal._initial();static final Animal _instance = Animal._initial();factory Animal() {return _instance;}
}void main() {/// animal为单例对象Animal animal = Animal();
}
2.6 构造函数的传递
构造函数可以进行传递,直接在小括号后面使用":",然后使用this调用其他的构造函数。
使用如下:
class Animal {Animal.initial() {print('animal inital');}Animal.create() : this.initial();
}main() {Animal animal = Animal.create();
}/// print result: animal inital
三 构造函数在继承中的使用
3.1 继承中构造函数使用规则
规则如下:
- 子类只能继承父类的无名无参构造函数(包含默认构造函数或者是自定义的无名无参构造函数)。
- 子类的构造函数中必须调用父类的构造函数。
dart默认帮子类自动调用父类的无名无参构造函数。
自定手动调用父类的构造函数。
3.1.1. 无名无参构造函数的继承与调用
父类有默认构造函数或者自定义了无名无参构造函数时,子类会自动继承父类的无名无参构造函数。
并且在子类调用任何形式的构造函数时,都会自动调用父类的无名无参构造函数。
父类没有自定义构造函数时:
class Animal {}class Dog extends Animal {Dog() {print('dog');}
}main() {Dog dog = Dog();
}///print result: dog
因为子类必须调用父类的构造函数,所以这里是自动调用了父类的默认构造函数。
父类自定义了无名无参构造函数时:
class Animal {
/// 自定义无名无参构造函数Animal() {print('animal');}/// 自定义命名构造函数Animal.initial() {print('animal initial');}
}class Dog extends Animal {Dog() {print('dog');}
}main() {Dog dog = Dog();
}/// print result: animal
/// print result: dog
父类存在无名无参构造函数,子类调用其他构造函数时:
class Animal {Animal() {print('animal');}Animal.initial() {print('animal initial');}
}class Dog extends Animal {Dog.initial() {print('dog initial');}
}main() {Dog dog = Dog.initial();
}/// print result: animal
/// print result: dog initial
3.1.2 子类手动调用父类的构造函数
这里需要提到一个初始化列表,这里仅简单的介绍。
子类在调用构造函数时的顺序是:
- 初始化列表
- 父类的构造函数
- 子类的构造函数
子类手动调用父类的构造函数就是需要在初始化列表中调用,格式为构造函数小括号后添加分号":" ,然后使用super调用。
使用如下:
class Animal {Animal.initial() {print('animal initial');}Animal.create() {print('animal create');}
}class Dog extends Animal {Dog() : super.initial();Dog.initial() : super.create();
}main() {Dog dog1 = Dog(); /// print result: animal initialDog dog2 = Dog.initial(); /// print result: animal create
}
3.2 初始化列表
初始化列表执行在构造函数之前,除了可以调用父类的构造函数之外,还可以初始化一些成员变量。初始化成员变量和调用父类的构造函数之间使用逗号","分隔。
特别是对于final修饰的成员变量,final变量在构造函数中是已经不能进行修改的。那么就可以在初始化列表中进行初始化。
使用如下:
class Animal {final double height;final double weight;Animal.initial(double weight, double height): height = height,weight = weight {print('animal initial');}
}main() {Animal animal = Animal.initial(100, 180);
}
初始化列表中还可以进行性aseert添加判断等应用。
后续文章中进行详细的记录。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
