Class Dart
是一个面向对象的语言,具有类和基于mixin的继承。每个对象都是一个class的实例,所有的class都是基于Object。
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 class Point { num x; num y; num z = 0 ; num d; Point(this .x, this .y); Point.origin() { x = 0 ; y = 0 ; } } void main() { var point = new Point(10 , 20 ); point.x = 4 ; assert (point.x == 4 ); assert (point.d == null ); }
构造函数 构造函数与继承 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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 class Point { var x; var y; Point(this .x, this .y); Point.withAssert(this .x, this .y): assert (x>= 0 ) { print ('in person.withAssert(): ($x , $y )' ); } Point.fromJson2(Map <String , num > json): x = json['x' ], y = json['y' ] { print ('In Person.fromJson2() : ($x , $y )' ); } Point.alongXAxis(num x): this (x, 0 ); } getDefaultData() {} class Person { String firstName; Person.fromJson(Map data) { print ('in Person' ); } } class Employee extends Person { Employee.fromJson(Map data): super .fromJson(data) { print ('in Employee' ); } Employee(): super .fromJson(getDefaultData()); } main() { var emp = new Employee.fromJson({}); if (emp is Person) { emp.firstName = 'Bob' ; } (emp as Person).firstName = 'bob' ; }
常量构造函数 如果你的类不需要改变,你可以将他写成编译时常量,但是要确保所有的实例变量都是final
。
1 2 3 4 5 6 7 8 9 class ImmutablePoint { static final ImmutablePoint origin = const ImmutablePoint(0 , 0 ); final num x, y; const ImmutablePoint(this .x, this .y); } const a = ImmutablePoint(1 ,2 );const b = ImmutablePoint(1 ,2 );assert (a == b);
工厂构造函数 在实现并不总是创建其类的新实例的构造函数时,请使用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 ; 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 12 class 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 2 3 4 5 6 7 8 9 10 class Rectangle { num left, top, width, height; Rectangle(this .left, this .top, this .width, this .height); num get right => left + width; set right(num value)=> left = value - width; num get bottom => top + height; set bottom(num value)=> top = value - height; }
Abstract methods/ Abstract Class 抽象类
1 2 3 4 5 6 7 abstract 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 class Person { final _name; Person(this ._name); String greet(String who) => 'Hello, $who . I am $_name ' ; } 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 2 3 4 5 6 7 8 9 10 11 12 class Television { void turnOn() { print ('television turnOn' ); } } class SmartTelevision extends Television { void turnOn() { super .turnOn(); print ('SmartTelevision' ); } }
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 2 3 4 class SmartTelevision extends Television { @override void turnOn() {} }
Overridable operators 重写操作符? 看看就好
Enumerated types 枚举类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 enum 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 25 class 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(); t.b(); TBAS b = new TBAS(); b.a(); b.b(); b.c(); }
Class variables and methods 静态方法与静态属性static
关键字实现
1 2 3 4 5 6 7 8 9 class Queue { static const name = 'queue' ; static num log(String str) { print (str); } } Queue.log(Queue.name);
Generics 泛型 泛型这块后面用到的话还要补,确实不是很熟
1 2 3 4 var name = List <String >();name.addAll(['a' ,'b' ]); name.add(2 );
类型限制 1 2 3 4 5 6 7 8 9 var names = <String >['a' , 'b' , 'c' ]; var uniqueNames = <String >{'a' , 'b' , 'c' }; var pages = <String , String > { 'index.html' : 'homePage' , } var nameSet = Set <String >.from(names);var newMap = Map <int , String >();print (names is List <String >);
Libraries 引入用import
关键字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import 'dart:html' ;import 'package:test/test.dart' ;import 'package:lib/lib.dart' as lib;import 'package:lib/lib.dart' show foo; import 'package:lib/lib.dart' hide foo; import 'package:greetings/hello.dart' deferred as hello;Future greet() async { await hello.loadLibrary(); hello.printGreeting(); }
创建一个库 create library packages
asynchrony support 异步支持 Dart一般用Future
和Stream
来处理异步。
handling Futures Future
使用await/async
,所以Futures
类似js
的Promise
?
1 2 3 4 Future checkVersion() async { var version = await lookUpVersion(); }
声明异步函数 如果函数没有返回值,则返回类型为 Future<void>
.
1 2 String lookUpVersion() => '1.0.0' ;Future<String > lookUpVersion() async => '1.0.0' ;
Handling Streams 使用 async
和 await for
1 2 3 4 5 6 7 await for (varOrType identifier in expression) { }
Generators emmm js
最讨厌的语法来到Dart
还是无法避免,之前处理异步都是promise
要不就是await
…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Iterable <int > naturalsTo(int n) sync * { int k = 0 ; while (k < n) yield k++; } Stream<int > asynchronousNaturalsTo(int n) async * { int k = 0 ; while (k < n) yield k++; } Iterable <int > naturalsDownFrom(int n) sync * { if (n > 0 ) { yield n; yield * naturalsDownFrom(n - 1 ); } }
Callable classes 可调用类 要实现类和方法一样的调用,则在类里面实现 call
方法.
1 2 3 4 5 6 7 8 class WannabeFunction { call(String a, String b, String c) => '$a $b $c !' ; } void main() { var wf = new WannabeFunction(); var out = wf("Hi" ,"there," ,"gang" ); print ('$out ' ); }
Typedefs 1 2 3 4 5 6 7 typedef Compare<T> = int Function (T a, T b);int sort(int a, int b) => a - b;void main() { assert (sort is Compare<int >); }