Class
Dart
是一个面向对象的语言,具有类和基于mixin的继承。每个对象都是一个class的实例,所有的class都是基于Object。
1 | // 所有未初始化的变量都为null |
构造函数
构造函数与继承
1 | class Point { |
常量构造函数
如果你的类不需要改变,你可以将他写成编译时常量,但是要确保所有的实例变量都是final
。
1 | class ImmutablePoint { |
工厂构造函数
在实现并不总是创建其类的新实例的构造函数时,请使用factory关键字。例如,工厂构造函数可能从缓存中返回实例,或者它可能返回子类型的实例。
注意 工厂构造函数不能访问this
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// 工厂构造函数,不需要经常实例化的情况,会从缓存获取
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);
}
}
Methods(方法)
Instance methods(实例方法)
普通的实例方法1
2
3
4
5
6
7
8
9
10
11
12class Point {
num x, y;
Point(this.x, this.y);
// 普通的方法
num distanceTo(Point other) {
var dx = x - other.x;
var dy = y - other.y;
return sqrt(dx * dx + dy * dy);
}
}
Getters && Setters
1 | class Rectangle { |
Abstract methods/ Abstract Class
抽象类1
2
3
4
5
6
7abstract class Doer {
void doSomething(); // 定义了一个抽象方法
}
class EffectiveDoer extends Doer {
void doSomething() { print('xxx'); } // 实现该方法
}
Implicit interfaces
接口和java很像1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32// implicit interfaces
// A person. The implicit interface contains greet().
class Person {
// In the interface, but visible only in this library
final _name;
// Not in the interface, since this is a constructor.
Person(this._name);
// In the interface
String greet(String who) => 'Hello, $who. I am $_name';
}
// an implementation of the Person interface.
class Impostor implements Person {
get _name => '';
String greet(String who)=> 'Hi $who. Do you know who I am?';
}
String greetBob(Person person)=> person.greet('Bob');
void main() {
print(greetBob(Person('Jsonz')));
print(greetBob(Impostor()));
}
// 多个接口
class Point implements Comparable, Location {
//...
}
extending a class扩展继承
1 | class Television { |
overriding members 重写方法
子类重写实例方法,但是有加和没加和什么区别呢?这个疑惑在stackoverflow有解答
@override
just points out that the function is also defined in an ancestor class, but is being redefined to do something else in the current class. It’s also used to annotate the implementation of an abstract method. It is optional to use but recommended as it improves readability.
1 | class SmartTelevision extends Television { |
Overridable operators
重写操作符? 看看就好
Enumerated types
枚举类型1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18enum Color { red, green, blue }
enums() {
// 枚举类型: 表示固定数量的常数值
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);
var aColor = Color.blue;
switch (aColor) {
case Color.red:
print('red');
break;
default:
print(aColor);
}
}
mixins
mixins
使用with
关键字,Class TAS = A with S
,则 TAS
包含了所有A
和S
的方法属性,以S
为最终覆盖,即如果A与S有相同的方法,则S覆盖A。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25class S {
a() { print('S.a'); }
}
class A {
a() { print('A.a'); }
b() { print('A.b'); }
}
class B {
a() { print('B.a'); }
b() { print('B.b'); }
c() { print('B.c'); }
}
class TAS = A with S;
class TBAS = B with A, S;
void main() {
TAS t = new TAS();
t.a(); // S.a
t.b(); // A.b
TBAS b = new TBAS();
b.a(); // S.a
b.b(); // A.b
b.c(); // B.c
}
Class variables and methods
静态方法与静态属性static
关键字实现1
2
3
4
5
6
7
8
9class Queue {
static const name = 'queue';
static num log(String str) {
print(str);
}
}
Queue.log(Queue.name);
Generics 泛型
泛型这块后面用到的话还要补,确实不是很熟
1 | var name = List<String>(); |
类型限制
1 | var names = <String>['a', 'b', 'c']; // list |
Libraries
引入用import
关键字
1 | // 引入 |
创建一个库
asynchrony support 异步支持
Dart一般用Future
和Stream
来处理异步。
handling Futures
使用await/async
,所以Futures
类似js
的Promise
?1
2
3
4Future checkVersion() async {
var version = await lookUpVersion();
// Do something with version
}
声明异步函数
如果函数没有返回值,则返回类型为 Future<void>
.1
2String lookUpVersion() => '1.0.0';
Future<String> lookUpVersion() async => '1.0.0';
Handling Streams
使用 async
和 await for
1
2
3
4
5
6
7// 1. 等待流的每一次值
// 2. 执行for循环的主体
// 3. 重复1和2直到流结束
// 4. 如果要中断流监听,可以用 break 或 return
await for (varOrType identifier in expression) {
// Executes each time the stream emits a value.
}
Generators
emmm js
最讨厌的语法来到Dart
还是无法避免,之前处理异步都是promise
要不就是await
…
1 | // 同步Generators |
Callable classes 可调用类
要实现类和方法一样的调用,则在类里面实现 call
方法.
1 | class WannabeFunction { |
Typedefs
1 | typedef Compare<T> = int Function(T a, T b); |