1、类和构造函数
class TestClass {
int a;
int b;
// 构造函数
TestClass(this.a, this.b);
// 可选构造函数
TestClass(this.a, {this.b = 0});
// 命名构造函数,命名构造函数不可以继承
TestClass.creat(this.a, this.b);
}
和
Java
一样,指定一个类型相同的方法就是普通构造函数。类里没有显示的构造函数,默认一个隐式的无参构造函数,会优先调用父类无参的构造函数。
2、初始化列表
class TestClass {
int a;
int b;
//初始化列表
TestClass(this.a) : b = 2;
TestClass(this.a) : b = 2 {
}
}
初始化列表的执行顺序在整个构造函数的最前面,作用:
- 可以调用父类的构造函数
- 在构造函数方法体之前,初始化一些成员变量
可以初始化
final
修饰的成员变量,因为执行方法体时,final
修饰的成员变量已经不能修改3、构造函数的调用顺序
如果子类继承父类,那么子类的构造函数要调用父类的构造函数,这时候分两种情况:
1、自动帮你调用父类的构造函数
2、显式调用父类的构造函数3.1、默认调用父类的无参构造函数
如果没有显式的调用父类的构造函数,并且父类有一个无参的构造函数,那么调用顺序如下:
初始化列表 —> 父类的无参的构造函数 —> 子类的无参的构造函数
如果父类没有无参的构造函数,就需要显式的调用父类的构造函数了3.2、显示调用父类构造函数
显示调用父类构造函数,应该在初始化列表中完成 ```dart class Person { String? name;
Person.fromJson(Map data) { print(‘in Person’); } }
class Man extends Person { Man.fromJson(Map data) : super.fromJson(data) { print(‘in Man’); } } //执行顺序 //in Person //in Man
<a name="eGUck"></a>
## 4、构造函数重定向
一个类中构造函数调用另一个构造函数实现重定向效果
```dart
class TestClass {
int a;
int b;
//初始化列表
TestClass(int a) : this.creat(a, 9);
TestClass.creat(this.a, this.b);
}
5、常量构造函数
使用const
函数进行修饰
class TestClass {
final String name;
const TestClass(this.name);
}
6、工厂构造函数
普通构造函数会默认返回创造出来的对象,工厂构造函数需要自己手动返回一个对象。
class TestClass {
String name;
String type;
static final Map<String, TestClass> _nameCache = {};
static final Map<String, TestClass> _typeCache = {};
TestClass(this.name, this.type);
factory TestClass.creatWithName(String name) {
if (_nameCache.containsKey(name)) {
return _nameCache[name]!;
} else {
final test = TestClass(name, "default");
_nameCache[name] = test;
return test;
}
}
factory TestClass.creatWithType(String type) {
if (_typeCache.containsKey(type)) {
return _typeCache[type]!;
} else {
final test = TestClass("default", type);
_typeCache[type] = test;
return test;
}
}
}
7、继承
dart
中不支持多继承,只支持单继承。见 3.2 显示调用父类构造函数 的示例
8、抽象类
可以只放类没有实现,但是抽象类不可以实例化
abstract class Test1 {
int test();
}
//同java,实体类继承抽象类后,必须实现抽象类的抽象方法
class Test2 extends Test1 {
@override
int test() {
// TODO: implement test
return 1;
}
}
9、隐式接口
跟java
中的继承还有点区别,当一个类当作接口使用时,必须实现这个接口中的所有方法
class Test1 {
void test() {}
}
class Test2 implements Test1 {
@override
void test() {
// TODO: implement test
}
}
10、混入(Mixin)
mixin
是一种在多类层次结构中复用代码的一种方式,允许子类在继承父类时混入其他类,实现多继承的效果。
mixin Walker {
void walk(String name){
print("$name is walking");
}
}
// 游泳
mixin Swimmer {
void swim(String name){
print("$name is swimming");
}
}
// 飞行
mixin Flyer {
void fly(String name){
print("$name is flying");
}
}
// 唱歌
mixin Singer {
void sing(String name){
print("$name is singing");
}
}
class Cat with Walker {}
class Duck with Walker, Swimmer, Flyer, Singer{}
使用with
关键字进行混入,后面可以有一个或多个混入的类名,混入后就可以使用混入的方法了。
10.1、混入的限制条件
使用on
关键字进行限制
mixin Singer on Bird{
void sing(String name){
print("$name is singing");
}
}
限制后就只能由Bird
类以及子类能够混入,其他类就无法混入,防止滥用。