Table of Content
Dart
是一门使用类单继承的语言, 所有对象都是类的实例, 且所有类都是 Object
类的子类。
定义类
类的定义使用 class
关键字。
class Point {
num x;
num y;
num z;
}
实例化
我们可以通过 new
关键字和构造函数进行类的实例化操作。一个类如果没有显式定义构造函数, 将会有默认的空构造函数。
var point = new Point();
print(point.hasCode);
构造函数
如果只是进行简单的参数传递赋值, 有两种简单的方式:
class Point {
num x;
num y;
num z;
// 第一个值传递给 this.x,第二个值传递给 this.y
Point(this.x, this.y, z) {
this.z = z;
}
class Point {
num x;
num y;
num z;
// 命名构造函数, 格式为 Class.name(var param)
Point.fromeList(var list):
x = list[0], y = list[1], z = list[2] { // 使用冒号初始化变量
}
// 这个构造函数可以简写为
// Point.fromeList(var list): this(list[0], list[1], list[2]);
}
常量构造函数
如果需要创建不可变的对象, 那么构造函数前需要添加 const
关键字:
class ImmutablePoint {
final num x;
final num y;
// 常量构造函数
const ImmutablePoint(this.x, this.y);
// 创建一个常量对象不能用 new,要用 const
static final ImmutablePoint origin = const ImmutablePoint(0, 0);
}
工厂构造函数
当前面提到的构造函数无法满足需求时, 你还可以选择工厂构造函数, 需要添加 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 = new Logger._internal(name);
_cache[name] = logger;
return logger;
}
}
Logger._internal(this.name);
void log(String msg) {
if (!mute) {
print(msg);
}
}
}
var logger = new Logger('UI');
logger.log('Button clicked');
继承
你可以通过 extends
关键字指明父类, 未指明父类时, 默认继承自 Object
类。
class Rectangle {
num x;
num y;
num width;
num height;
Rectangle(num this.height, num this.width);
}
// Square 继承 Rectangle
class Square extends Rectangle {
// 调用超类的构造函数
Square(num size): super(size, size);
}
toString()
你可以选择为一个类实现 String toString()
函数:
class Point {
num x;
num y;
Point(this.x, this.y) {}
String toString() => 'Point(x: $x, y: $y)';
}
void main() {
var p = new Point(1, 2);
print(p); // 默认调用 toString() 函数
}
Getter & Setter
每一个字段都对应一对隐式的 Getter/Setter。对于常量, 则只有 Getter 方法。
你可以使用 get
/set
进行扩展:
class Rectangle {
num x;
num y;
num width;
num height;
Rectangle(this.x, this.y, this.width, this.height);
// right 和 bottom 两个属性的计算方法:
num get right => x + width;
set right(num value) => x = value - width;
num get bottom => y + height;
set bottom(num value) => y = value - height;
}
main() {
var rect = new Rectangle(3, 4, 20, 15);
assert(rect.x == 3);
rect.right = 12;
assert(rect.x == -8);
}
抽象类/接口
通过 abstract
我们可以定义一个抽象类/接口。抽象类不可以无法实例化, 通过 implements
指明并实现。抽象方法不需要关键字声明, 直接使用 ;
结束即可。
// 定义 Shape 抽象类/接口
abstract class Shape {
// 抽象方法, 是隐式接口的一部分
num perimeter();
}
// 为 Rectangle 实现 Shape 接口
class Rectangle implements Shape {
final num height, width;
Rectangle(num this.height, num this.width);
// 实现了 Shape 接口要求的 perimeter 方法
num perimeter() => 2 * height + 2 * width;
}
// Square 继承 Rectangle
class Square extends Rectangle {
// 调用超类的构造函数
Square(num size): super(size, size);
}