Dart 是一种面向对象的语言,具有类和基于 mixin 的继承。
每个对象都是一个类的实例,所有的类都是 Object 的子类。无论数字、函数和 null 都是对象。
创建对象的时候,new 可以去掉(建议去掉)
基于 mixin 的继承意味着,尽管每个类(除了 Object )都只有一个超类,但类主体可以在多个类层次结构中重用。
构造函数
class Point {
num x, y;
Point(num x, num y) {
this.x = x;
this.y = y;
}
}
等价的更简单的写法
class Point {
num x, y;
Point(this.x, this.y); //没有函数体直接分号结束
}
如果不声明构造函数,则提供默认构造函数。
默认构造函数没有参数,并调用超类中无参数构造函数。
子类不从父类继承构造函数。没有声明构造函数的子类只有默认的构造函数(没有参数,没有名称)而不是从父类继承的构造函数。
命名的构造函数
使用命名构造函数可以在一个类中定义多个构造函数,或者让一个类的作用对于开发人员来说更清晰:
class Point {
num x, y;
Point(this.x, this.y);
Point.origin(){
this.x = 0;
this.y = 0;
}
}
调用:
Point point = Point.origin();
调用非默认的超类构造函数
默认情况下,子类中的构造函数调用父类的未命名的无参数构造函数。父类的构造函数在构造函数体的开始处被调用。如果类中有使用初始化列表,初始化列表将在调用超类之前执行。
如果超类没有未命名的无参数构造函数,则必须手动调用超类中的一个构造函数。在冒号 : 之后,在构造函数体(如果有的话)之前指定超类构造函数。
void main(){
Student stu = Student.info("lee", 28, "Dart");
}
class Person {
String name;
int age;
Person.info(this.name, this.age);
}
class Student extends Person {
String book;
//手动调用super.info
Student.info(String name, int age, String book) : super.info(name, age);
}
初始化列表
除了调用超类构造函数之外,还可以在构造函数主体运行之前初始化实例变量。初始值设定项用逗号分开。
class Person {
String mName;
int mAge;
Person(String name, int age): mName = name, mAge = age;
}
初始化器的右边部分中无法访问 this 关键字。
在开发期间,可以通过在初始化列表中使用 assert 来验证输入。
Person(String name, int age): assert(name.isEmpty){}
重定向构造函数
class Person {
String mName;
int mAge;
Person(this.mName, this.mAge);
Person.info(String name, int age): this(name, age);
}
如果类生成的对象不会改变,可以使这些对象成为编译时常量。为此,定义一个 const 构造函数,并确保所有实例变量都是 final 的。
class Person {
final String mName;
final int mAge;
static Person getInstance = const Person("lee", 28);
const Person(this.mName, this.mAge);
}
工厂构造函数
在实现构造函数时使用 factory 关键字,该构造函数并不总是创建类的新实例。例如,工厂构造函数可以从缓存返回实例,也可以返回子类型的实例。
以下示例演示工厂构造函数从缓存返回对象:
class Logger {
final String name;
bool mute = false;
// 缓存对象
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);
}
}
工厂构造函数不能访问 this 关键字。
调用工厂构造函数,就像调用其他构造函数一样;
方法
实例方法
class Person {
String getName(){
return "lee";
}
}
getter/setter
所有实例变量都生成隐式 getter 方法。非最终实例变量也生成隐式 setter 方法。
class Rectangle {
num left, top, width, height;
Rectangle(this.left, this.top, this.width, this.height);
// 定义两个属性,right 和 bottom,它们的 getter 和 setter 需要计算,不能用默认的了
num get right => left + width;
set right(num value) => left = value - width;
num get bottom => top + height;
set bottom(num value) => top = value - height;
}
void main() {
var rect = Rectangle(3, 4, 20, 15);
assert(rect.left == 3);
rect.right = 12;
assert(rect.left == -8);
}
网友评论