- 基于 mixin 的继承
- 根类是 Object
使用类成员
- 数据
- 函数
var p = Point(2, 2);// Set the value of the instance variable y.p.y = 3;// Get the value of y.assert(p.y == 3);// Invoke distanceTo() on p.double distance = p.distanceTo(Point(4, 4));
?.避免对象为 null
// If p is non-null, set its y value to 4.p?.y = 4;
使用构造函数
构造函数可以是:
- ClassName
- ClassName.identifier
var p1 = Point(2, 2);var p2 = Point.fromJson({'x': 1, 'y': 2});
- new 关键字是可选的
var p1 = new Point(2, 2);var p2 = new Point.fromJson({'x': 1, 'y': 2});
- 常量构造函数
var p = const ImmutablePoint(2, 2);
- 创建两次常量对象, 它们是相同的对象
var a = const ImmutablePoint(1, 1);var b = const ImmutablePoint(1, 1);assert(identical(a, b)); // They are the same instance!
- 不用写过多 const 关键字
// 声明出所有 const// Lots of const keywords here.const pointAndLine = const {'point': const [const ImmutablePoint(0, 0)],'line': const [const ImmutablePoint(1, 10), const ImmutablePoint(-2, 11)],};// Only one const, which establishes the constant context.const pointAndLine = {'point': [ImmutablePoint(0, 0)],'line': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)],};
获取对象类型
- 返回类型对象
- 运行时类型 runtimeType
print('The type of a is ${a.runtimeType}');
实例变量
- 每个实例变量隐含实现 getter 方法
- 每个非 finall 实例变量隐含实现 setter 方法
class Point {double x; // Declare instance variable x, initially null.double y; // Declare y, initially null.double z = 0; // Declare z, initially 0.}class Point {double x;double y;}void main() {var point = Point();point.x = 4; // Use the setter method for x.assert(point.x == 4); // Use the getter method for x.assert(point.y == null); // Values default to null.}
构造函数
- 与类名相同
- 命名构造函数
- this
class Point {double x, y;Point(double x, double y) {// There's a better way to do this, stay tuned.this.x = x;this.y = y;}}
- 给实例变量赋值的语法糖
class Point {double x, y;// Syntactic sugar for setting x and y// before the constructor body runs.Point(this.x, this.y);}
默认构造函数
如果没声明构造函数, dart 将会创建一个没有参数的构造函数, 并且调用父类的无参构造函数.
构造函数不会继承
没声明构造函数的子类只有默认的无参构造函数.
命名构造函数
- 实现多个构造函数
class Point {double x, y;Point(this.x, this.y);// Named constructorPoint.origin() {x = 0;y = 0;}}
调用非默认超类构造函数
- 默认情况下, 子类构造函数会调用父类非命名无参构造函数, 调用位置是子类构造函数体的开始.
各构造函数执行顺序:
- 初始化列表
- 父类无参构造函数
- 子类无参构造函数
- 如果父类没有未命名的无参构造函数, 那么需要使用
:符号来明确调用父类的一个构造函数 :是初始化列表, 就是在子类没有创建之前, 使用初始化列表来初始化父类, 有了父类才能有子类
class Person {String firstName;Person.fromJson(Map data) {print('in Person');}}class Employee extends Person {// Person does not have a default constructor;// you must call super.fromJson(data).Employee.fromJson(Map data) : super.fromJson(data) {print('in Employee');}}main() {var emp = new Employee.fromJson({});// Prints:// in Person// in Employeeif (emp is Person) {// Type checkemp.firstName = 'Bob';}(emp as Person).firstName = 'Bob';}
初始化列表
:- 使用
,分隔 - 不能使用
this
// Initializer list sets instance variables before// the constructor body runs.Point.fromJson(Map<String, double> json): x = json['x'],y = json['y'] {print('In Point.fromJson(): ($x, $y)');}
- 在开发模型下, 用于验证参数
Point.withAssert(this.x, this.y) : assert(x >= 0) {print('In Point.withAssert(): ($x, $y)');}
- 初始化 final 字段
import 'dart:math';class Point {final num x;final num y;final num distanceFromOrigin;Point(x, y): x = x,y = y,distanceFromOrigin = sqrt(x * x + y * y);}main() {var p = new Point(2, 3);print(p.distanceFromOrigin);}
重定向构造函数
class Point {double x, y;// The main constructor for this class.Point(this.x, this.y);// Delegates to the main constructor.Point.alongXAxis(double x) : this(x, 0);}
常量构造函数
- 只要确保所有字段是 final 的
class ImmutablePoint {static final ImmutablePoint origin =const ImmutablePoint(0, 0);final double x, y;const ImmutablePoint(this.x, this.y);}
工厂构造函数
- factory 关键字
- 可能不会创建新实例, 会从缓存中取出实例
- factory 无法访问 this
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) {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);}}// 与普通构造函数使用方法相同var logger = Logger('UI');logger.log('Button clicked');var logMap = {'name': 'UI'};var loggerJson = Logger.fromJson(logMap);
方法
实例方法
import 'dart:math';class Point {double x, y;Point(this.x, this.y);double distanceTo(Point other) {var dx = x - other.x;var dy = y - other.y;return sqrt(dx * dx + dy * dy);}}
Getters 和 Setters
class Rectangle {double left, top, width, height;Rectangle(this.left, this.top, this.width, this.height);// Define two calculated properties: right and bottom.double get right => left + width;set right(double value) => left = value - width;double get bottom => top + height;set bottom(double value) => top = value - height;}void main() {var rect = Rectangle(3, 4, 20, 15);assert(rect.left == 3);rect.right = 12;assert(rect.left == -8);}
抽象方法
- 抽象方法必须在抽象类中
abstract class Doer {// Define instance variables and methods...void doSomething(); // Define an abstract method.}class EffectiveDoer extends Doer {void doSomething() {// Provide an implementation, so the method is not abstract here...}}
抽象类
// This class is declared abstract and thus// can't be instantiated.abstract class AbstractContainer {// Define constructors, fields, methods...void updateChildren(); // Abstract method.}
隐式接口
- 每个类隐式创建接口
// 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('Kathy')));print(greetBob(Impostor()));}
- 实现多个接口
class Point implements Comparable, Location {...}
扩展类
- extends: 创建子类
- super: 引用父类
class Television {void turnOn() {_illuminateDisplay();_activateIrSensor();}// ···}class SmartTelevision extends Television {void turnOn() {super.turnOn();_bootNetworkInterface();_initializeMemory();_upgradeApps();}// ···}
重载成员
@override
class SmartTelevision extends Television {@overridevoid turnOn() {...}// ···}
可重载的操作符

class Vector {final int x, y;Vector(this.x, this.y);Vector operator +(Vector v) => Vector(x + v.x, y + v.y);Vector operator -(Vector v) => Vector(x - v.x, y - v.y);// Operator == and hashCode not shown. For details, see note below.// ···}void main() {final v = Vector(2, 3);final w = Vector(2, 2);assert(v + w == Vector(4, 5));assert(v - w == Vector(0, 1));}
- 重写
==时, 要求同时重写对象的hashCode
noSuchMethod()
- 在使用不存在的方法或实例变量时作出反应, 可以实现 noSuchMethod()
class A {// Unless you override noSuchMethod, using a// non-existent member results in a NoSuchMethodError.@overridevoid noSuchMethod(Invocation invocation) {print('You tried to use a non-existent member: ' +'${invocation.memberName}');}}
扩展方法
import 'string_apis.dart';...print('42'.padLeft(5)); // Use a String method.print('42'.parseInt()); // Use an extension method.
枚举类型
使用枚举
- 声明
enum Color { red, green, blue }
- 每个枚举值有一个
index属性
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);
- 在 switch 中使用枚举
var aColor = Color.blue;switch (aColor) {case Color.red:print('Red as roses!');break;case Color.green:print('Green as grass!');break;default: // Without this, you see a WARNING.print(aColor); // 'Color.blue'}
Mixins
多重继承.
class Musician extends Performer with Musical {// ···}class Maestro extends Personwith Musical, Aggressive, Demented {Maestro(String maestroName) {name = maestroName;canConduct = true;}}
- mixins 类
mixin Musical {bool canPlayPiano = false;bool canCompose = false;bool canConduct = false;void entertainMe() {if (canPlayPiano) {print('Playing piano');} else if (canConduct) {print('Waving hands');} else {print('Humming to self');}}}
- 指定该 mixins 只能用在某类
mixin MusicalPerformer on Musician {// ···}
类变量和类方法
- static
静态变量
class Queue {static const initialCapacity = 16;// ···}void main() {assert(Queue.initialCapacity == 16);}
静态方法
import 'dart:math';class Point {double x, y;Point(this.x, this.y);static double distanceBetween(Point a, Point b) {var dx = a.x - b.x;var dy = a.y - b.y;return sqrt(dx * dx + dy * dy);}}void main() {var a = Point(2, 2);var b = Point(4, 4);var distance = Point.distanceBetween(a, b);assert(2.8 < distance && distance < 2.9);print(distance);}
