Dart 是支持基于 mixin 继承机制的面向对象语言,所有对象都是一个类的实例,而除了 Null 以外的所有的类都继承自 Object 类。基于 mixin 的继承 意味着尽管每个类 (top class Object? 除外) 都有一个超类,一个类的代码可以在其他多个类继承中重复使用。扩展方法 是一种在不更改类或创建子类的情况下向类添加功能的方式。
类的成员
对象的成员由函数和数据 (即 方法 和 实例变量)组成。方法的调用要通过对象来完成,这种方式可以访问对象的函数和数据。
使用 (.)来访问对象的实例变量
1 2 3 4 var p = Point(2 , 2 );assert (p.y == 2 );double distance = p.distanceTo(Point(4 , 4 ));
使用 ?. 代替 . 可以避免因为左边表达式为 null 而导致的问题
对象的类型 1 2 3 4 5 var a = const ImmutablePoint(0 , 0 );
实例变量 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 class Point { double? x; double? y; double z = 0 ; } var point = Point1();point.x = 1 ; class Point1 { double? x; double? y; } var mark = ProfileMark('11' );class ProfileMark { final String name; final DateTime start = DateTime .now(); ProfileMark(this .name); ProfileMark.unnamed() : name = '' ; }
构造函数
声明一个与类名一样的函数即可声明一个构造函数 (对于命名式构造函数 还可以添加额外的标识符)。大部分构造函数形式是生成式构造函数,其用于创建一个类的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 class Point1 { double x = 0 ; double y = 0 ; Point1(double x, double y) { this .x = x; this .y = y; } }
1 2 3 4 5 6 7 8 class Point1 { double x = 0 ; double y = 0 ; Point1(this .x, this .y); }
默认构造函数:如果没有声明构造函数,那么Dart 会自动生成一个无参数的构造函数并且该构造函数会调用其父类的去参数构造方法。
构造函数不被继承:子类不会继承父类的构造函数,如果子类没有声明构造函数,那么只会有一个默认无参数的构造函数。
命名式构造函数
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 var p = Point1(2 , 2 );var p1 = Point1.origin();var p2 = Point1.test(2 , 2 );const double xOrigin = 0 ;const double yOrigin = 0 ;class Point1 { final double x; final double y; Point1(this .x, this .y); Point1.origin() : x = xOrigin, y = yOrigin; Point1.test(double x, double y) : this .x = x, this .y = y; }
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 var employee = Employee.fromJson({}); class Person { String? firstName; Person.fromJson(Map data) { print ('in Person' ); } } class Employee extends Person { Employee.fromJson(super .data) : super .fromJson() { print ("in Employee" ); } } class Employee extends Person { Employee() : super .fromJson({}); }
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 class Vector2d { final double x; final double y; Vector2d(this .x, this .y); } class Vector3d extends Vector2d { final double z; Vector3d(super .x, super .y, this .z); } class Vector2d { final double x; final double y; Vector2d(this .x, this .y); Vector2d.named({required this .x, required this .y}); } class Vector3d extends Vector2d { final double z; Vector3d(super .x, super .y, this .z); Vector3d.yzPlane({required super .y, required this .z}) : super .named(x: 0 ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Point1 { final double x; final double y; final double distanceFromOrigin; Point1.test(double x, double y) : this .x = x, this .y = y, distanceFromOrigin = sqrt(x * x + y * y); }
1 2 3 4 5 6 7 8 9 class Point { double x, y; Point(this .x, this .y); Point.alongXAsis(double x) : this (x, 0 ); }
1 2 3 4 5 6 7 8 9 class ImmutablePoint { static const ImmutablePoint origin = ImmutablePoint(0 , 0 ); final double x, y; const ImmutablePoint(this .x, this .y); }
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 var logger = Logger('name' );var logMap = {'name' : 'UI' };var loggerJson = Logger.fromJson(logMap);class Logger { final String name; bool mute = false ; static final Map <String , Logger> _cache = <String , Logger>{}; factory Logger(String name) { return _cache.putIfAbsent(name, () => Logger._internal(name)); } factory Logger.fromJson(Map <String , Object > json) { return Logger(json['name' ].toString()); } Logger._internal(this .name); void log(String msg) { if (!mute) print (msg); } }
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Point { final double x; final double y; Point(this .x, this .y); double distanceTo(Point other) { var dx = x - other.x; var dy = y - other.y; return sqrt(dx * dy); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var rect = Rectangle(3 , 4 , 20 , 15 );rect.right = 10 ; class Rectangle { double left, top, width, height; Rectangle(this .left, this .top, this .width, this .height); double get right => left + width; set right(double value) => left = value - width; double get bottom => top + height; set bottom(double value) => top = value - height; }
1 2 3 4 5 6 7 8 9 10 11 12 abstract class Doer { void doSomething(); } class EffectiveDoer extends Doer { void doSomething() { } }
抽象类 1 2 3 4 5 abstract class Doer { void doSomething(); }
隐式接口 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 class Person { final String _name; Person(this ._name); String greet(String who) => 'Hello, $who . I am $_name ' ; } class Impostor implements Person { String get _name => '' ; String greet(String who) => 'Hi $who . Do you know who I am?' ; } String greetBob(Person person) => person.greet('Bob' );class Point implements A , B { ... }