Fork me on GitHub

Dart学习笔记 - 类

Classes

Dart 是一个面向对象编程语言,同时支持级域mixin的继承机制。每个对象都是一个类的实例,所有类都继承于Object

定义一个类

没有初始化的属性值都为null

class Point {
    num x;
    num y;
    num z = 0;
}
main(List<String> args) {
    var point = new Point();
    print(point.x);// null
}

Constructors 构造函数

定义一个和类名字一样的方法就定义了一个构造函数。

常见的构造函数:

class Point {
    num x;
    num y;
    Point(num x, num y) {
        this.x = x;
        this.y = y;
    }
}

Dart 提供语法糖简化上面的构造函数。

class Point {
    num x;
    num y;
    Point(this.x, this.y);
}

命名构造函数。使用命名构造函数可以为一个类实现多个构造函数,或者使用命名构造函数来更清晰的表明你的意图。

class Point {
    num x;
    num y;
    Point(this.x, this.y);
    // 命名构造函数
    Point.fromOther(Point p) {
        this.x = p.x;
        this.y = p.y;
    }
}
main(List<String> args) {
    var point = new Point(1, 2);
    var temp = Point.fromOther(point);
    print(temp.x);
}

注:

  • 如果没有定义构造函数,则会有个默认构造函数。默认构造函数没有参数,并且会调用超类的没有参数的构造函数。
  • 子类不会继承超类的构造函数。

Initializer list 初始化列表

构造函数体执行前,还可以初始化实例参数。使用逗号分隔初始化表达式。

class Point {
    num x;
    num y;
    Point(this.x, this.y);
    Point.fromOther(Point p)
        :  x = p.x,
           y = p.y {
        print(p.x.toString() + '-' + p.y.toString());
    }
}

初始化表达式等号右边的部分不能访问this(不能访问实例属性和方法)

Redirecting constructors 重定向构造函数

使用冒号调用其它构造函数。函数体中是无法调用的。

class Point {
    num x;
    num y;
    Point(this.x, this.y);
    Point.fromOther(Point p) : this(p.x, p.y);
}

Constant constructors 常量构造函数

如果你的类提供一个状态不变的对象,你可以把这些对象定义为编译时常量。要实现这个功能。需要定义一个const构造函数,并且声明所有类的变量为final

class Point {
    final num x;
    final num y;
    const Point(this.x, this.y);
    // 不变对象
    static final Point origin = const Point(0, 0);
}
main(List<String> args) {
    print(Point.origin.x);
}

Factory constructors 工厂方法构造函数

如果一个构造函数并不总是返回一个新的对象,则使用factory来定义这个构造函数。例如,一个工厂构造函数可能从缓存中获取一个实例并返回,或者返回一个子类型实例。

class Point {
    final num x;
    final num y;
    static final Map<String, Point> _cache = <String, Point>{};
    // 工厂方法构造函数
    factory Point(num x, num y) {
        var key = x.toString() + ',' + y.toString();
        if (_cache.containsKey(key)) {
            return _cache[key];
        } else {
            final point = Point._init(x, y);
            _cache[key] = point;
            return point;
        }
    }
    Point._init(this.x, this.y);
}
main(List<String> args) {
    var p1 = new Point(1, 2);
    var p2 = new Point(1, 2);
    print(p1 == p2); // true
}

注意:工厂构造函数无法访问this。

Methods 函数

函数是类定义的方法,是类对象的行为。

Instance methods 实例函数

对象的实例函数可以访问this

class Point {
    num x;
    num y;
    Point(this.x, this.y);
    // 实例函数
    Point nextPoint() {
        return new Point(this.x + 1, this.y + 1);
    }
    @override
    String toString() {
        return 'x:' + this.x.toString() + ',y:' + this.y.toString();
    }
}
main(List<String> args) {
    var p = new Point(1, 2);
    print(p.nextPoint());
}

Getters and setters

Getters和setters是用来设置和访问对象属性的特殊函数。每个实例变量都隐含的具有一个getter,如果变量不是final的则还有一个setter。你直接通过getter和setter来创建新的属性,使用getset关键字定义getter和setter:

class Point {
    num x = 0;
    num y = 0;
    // getter
    num get xNext => x + 1;
    // setter
    set xNext(num x) => this.x = x - 1;
}
main(List<String> args) {
    var p = new Point();
    p.xNext = 3;
    print(p.x); // 2
}