Dart

作者: WRFranky | 来源:发表于2019-05-13 14:25 被阅读0次

    Dart 的模块导入。

    模块导入 模块导出给别人用

    和 Java 不同的是,Dart 没有 public、 protected、 和 private 关键字。如果一个标识符以 (_) 开头,则该标识符 在库内是私有的。详情请参考: 库和可见性

    http://dart.goodev.org/guides/language/language-tour#booleans%E5%B8%83%E5%B0%94%E5%80%BC

    Default value(默认值):

    没有初始化的变量自动获取一个默认值为 null。类型为数字的 变量如何没有初始化其值也是 null,不要忘记了 数字类型也是对象。

    int lineCount;

    // Variables (even if they will be numbers) are initially null.

    assert(lineCount == null);

    注意: 在生产模式 assert() 语句被忽略了。在检查模式 assert(condition) 会执行,如果条件不为 true 则会抛出一个异常。详情请参考 Assert 部分。

    Dart使用到的关键字

    Optional types(可选的类型):

    在声明变量的时候,你可以选择加上具体 类型:

    String name = 'Bob';

    添加类型可以更加清晰的表达你的意图。 IDE 编译器等工具有可以使用类型来更好的帮助你, 可以提供代码补全、提前发现 bug 等功能。

    注意: 对于局部变量,这里准守 代码风格推荐 部分的建议,使用 var 而不是具体的类型来定义局部变量。

    Final and const:

    如果你以后不打算修改一个变量,使用 final 或者 const。 一个 final 变量只能赋值一次;一个 const 变量是编译时常量。 (Const 变量同时也是 final 变量。) 顶级的 final 变量或者类中的 final 变量在 第一次使用的时候初始化。

    注意: 实例变量可以为 final 但是不能是 const 。

    下面是 final 变量的示例:

    final name = 'Bob'; // Or: final String name = 'Bob';

    // name = 'Alice';  // Uncommenting this causes an error

    const 变量为编译时常量。 如果 const 变量在类中,请定义为 static const。 可以直接定义 const 和其值,也 可以定义一个 const 变量使用其他 const 变量的值来初始化其值。

    const bar = 1000000;      // Unit of pressure (dynes/cm2)const atm = 1.01325 * bar; // Standard atmosphere

    const 关键字不仅仅只用来定义常量。 有可以用来创建不变的值, 还能定义构造函数为 const 类型的,这种类型 的构造函数创建的对象是不可改变的。任何变量都可以有一个不变的值。

    // Note: [] creates an empty list.// const [] creates an empty, immutable list (EIA).

    var foo = const [];  // foo is currently an EIA.

    final bar = const []; // bar will always be an EIA.

    const baz = const []; // baz is a compile-time constant EIA.

    // You can change the value of a non-final, non-const variable,// even if it used to have a const value.foo = [];// You can't change the value of a final or const variable.// bar = []; // Unhandled exception.// baz = []; // Unhandled exception.

    关于使用 const 来创建不变的值的更多信息,请参考: Lists、 Maps、 和 Classes


    Numbers(数值)

    Dart 支持两种类型的数字:

    int

    整数值,其取值通常位于 -253 和 253 之间。

    double

    64-bit (双精度) 浮点数,符合 IEEE 754 标准。

    int 和 double 都是 num 的子类。 num 类型定义了基本的操作符,例如 +, -, /, 和 *, 还定义了abs()、 ceil()、和 floor() 等 函数。 (位操作符,例如 >> 定义在 int 类中。) 如果 num 或者其子类型不满足你的要求,请参考 dart:math 库。

    注意: 不在 -253 到 253 范围内的整数在 Dart 中的行为 和 JavaScript 中表现不一样。 原因在于 Dart 具有任意精度的整数,而 JavaScript 没有。 参考 问题 1533 了解更多信息。

    整数是不带小数点的数字。下面是一些定义 整数的方式:

    var x = 1;var hex = 0xDEADBEEF;var bigInt = 34653465834652437659238476592374958739845729;

    如果一个数带小数点,则其为 double, 下面是定义 double 的一些方式:

    var y = 1.1;var exponents = 1.42e5;

    下面是字符串和数字之间转换的方式:

    // String -> intvar one = int.parse('1');assert(one == 1);// String -> doublevar onePointOne = double.parse('1.1');assert(onePointOne == 1.1);// int -> StringString oneAsString = 1.toString();assert(oneAsString == '1');// double -> StringString piAsString = 3.14159.toStringAsFixed(2);assert(piAsString == '3.14');

    整数类型支持传统的位移操作符,(<<, >>), AND (&), 和 OR (|) 。例如:

    assert((3 << 1) == 6);  // 0011 << 1 == 0110

    assert((3 >> 1) == 1);  // 0011 >> 1 == 0001

    assert((3 | 4)  == 7);  // 0011 | 0100 == 0111

    数字字面量为编译时常量。 很多算术表达式 只要其操作数是常量,则表达式结果 也是编译时常量。

    const msPerSecond = 1000;

    const secondsUntilRetry = 5;

    const msUntilRetry = secondsUntilRetry * msPerSecond;

    Strings(字符串)

    Dart 字符串是 UTF-16 编码的字符序列。 可以使用单引号或者双引号来创建字符串:

    var s1 = 'Single quotes work well for string literals.';

    var s2 = "Double quotes work just as well.";

    var s3 = 'It\'s easy to escape the string delimiter.';

    var s4 = "It's even easier to use the other delimiter.";

    可以在字符串中使用表达式,用法是这样的: ${expression}。如果表达式是一个比赛服,可以省略 {}。 如果表达式的结果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串。

    var s = 'string interpolation';

    assert('Dart has $s, which is very handy.' ==      'Dart has string interpolation, ' +      'which is very handy.');

    assert('That deserves all caps. ' +      '${s.toUpperCase()} is very handy!' ==      'That deserves all caps. ' +      'STRING INTERPOLATION is very handy!');

    注意: == 操作符判断两个对象的内容是否一样。 如果两个字符串包含一样的字符编码序列, 则他们是相等的。

    可以使用 + 操作符来把多个字符串链接为一个,也可以把多个 字符串放到一起来实现同样的功能:

    var s1 = 'String ' 'concatenation'        " works even over line breaks.";

    assert(s1 == 'String concatenation works even over '            'line breaks.');var s2 = 'The + operator '        + 'works, as well.';assert(s2 == 'The + operator works, as well.');

    使用三个单引号或者双引号也可以 创建多行字符串对象:

    var s1 = '''

    You can create

    multi-line strings like this one.

    ''';var s2 = """This is also a

    multi-line string.""";

    通过提供一个 r 前缀可以创建一个 “原始 raw” 字符串:

    var s = r"In a raw string, even \n isn't special.";

    Booleans(布尔值)

    为了代表布尔值,Dart 有一个名字为 bool 的类型。 只有两个对象是布尔类型的:true 和 false 所创建的对象, 这两个对象也都是编译时常量。

    当 Dart 需要一个布尔值的时候,只有 true 对象才被认为是 true。 所有其他的值都是 flase。这点和 JavaScript 不一样, 像 1、 "aString"、 以及 someObject 等值都被认为是 false。

    例如,下面的代码在 JavaScript 和 Dart 中都是合法的代码:

    var name = 'Bob';if (name) {  // Prints in JavaScript, not in Dart.  print('You have a name!');}

    如果在 JavaScript 中运行,则会打印出 “You have a name!”,在 JavaScript 中 name 是非 null 对象所以认为是 true。但是在 Dart 的生产模式下 运行,这不会打印任何内容,原因是 name 被转换为 false了,原因在于 name != true。 如果在 Dart 检查模式运行,上面的 代码将会抛出一个异常,表示 name 变量不是一个布尔值。

    下面是另外一个在 JavaScript 和 Dart 中表现不一致的示例:

    if (1) {  print('JS prints this line.');} else {  print('Dart in production mode prints this line.');  // However, in checked mode, if (1) throws an  // exception because 1 is not boolean.}

    注意: 上面两个示例只能在 Dart 生产模式下运行, 在检查模式下,会抛出异常表明 变量不是所期望的布尔类型。

    Dart 这样设计布尔值,是为了避免奇怪的行为。很多 JavaScript 代码 都遇到这种问题。 对于你来说,在写代码的时候你不用这些写代码: if (nonbooleanValue),你应该显式的 判断变量是否为布尔值类型。例如:

    // Check for an empty string.var fullName = '';assert(fullName.isEmpty);// Check for zero.var hitPoints = 0;assert(hitPoints <= 0);// Check for null.var unicorn;assert(unicorn == null);// Check for NaN.var iMeantToDoThis = 0 / 0;assert(iMeantToDoThis.isNaN);

    Lists(列表)

    也许 array (或者有序集合)是所有编程语言中最常见的集合类型。 在 Dart 中数组就是 List 对象。所以 通常我们都称之为 lists

    Dart list 字面量和 JavaScript 的数组字面量类似。下面是一个 Dart list 的示例:

    var list = [1, 2, 3];

    Lists 的下标索引从 0 开始,第一个元素的索引是 0. list.length - 1 是最后一个元素的索引。 访问 list 的长度和元素与 JavaScript 中的用法一样:

    var list = [1, 2, 3];assert(list.length == 3);assert(list[1] == 2);list[1] = 1;assert(list[1] == 1);

    在 list 字面量之前添加 const 关键字,可以 定义一个不变的 list 对象(编译时常量):

    var constantList = const [1, 2, 3];// constantList[1] = 1; // Uncommenting this causes an error.

    List 类型有很多函数可以操作 list。 更多信息参考 泛型 和 集合

    Maps

    通常来说,Map 是一个键值对相关的对象。 键和值可以是任何类型的对象。每个  只出现一次, 而一个值则可以出现多次。Dart 通过 map 字面量 和 Map 类型支持 map。

    下面是一些创建简单 map 的示例:

    var gifts = {

    // Keys      Values  

    'first' : 'partridge',  

    'second': 'turtledoves', 

     'fifth' : 'golden rings'

    };

    var nobleGases = {// Keys  Values  2 :  'helium',  10:  'neon',  18:  'argon',};

    使用 Map 构造函数也可以实现同样的功能:

    var gifts = new Map();

    gifts['first'] = 'partridge';

    gifts['second'] = 'turtledoves';

    gifts['fifth'] = 'golden rings';

    var nobleGases = new Map();

    nobleGases[2] = 'helium';

    nobleGases[10] = 'neon';

    nobleGases[18] = 'argon';

    往 map 中添加新的键值对和在 JavaScript 中的用法一样:

    var gifts = {'first': 'partridge'};

    gifts['fourth'] = 'calling birds'; // Add a key-value pair

    获取 map 中的对象也和 JavaScript 的用法一样:

    var gifts = {'first': 'partridge'};

    assert(gifts['first'] == 'partridge');

    如果所查找的键不存在,则返回 null:

    var gifts = {'first': 'partridge'};assert(gifts['fifth'] == null);

    使用 .length 来获取 map 中键值对的数目:

    var gifts = {'first': 'partridge'};

    gifts['fourth'] = 'calling birds';

    assert(gifts.length == 2);

    同样使用 const 可以创建一个 编译时常量的 map:

    final constantMap = const {  2: 'helium',  10: 'neon',  18: 'argon',};// constantMap[2] = 'Helium'; // Uncommenting this causes an error.

    关于 Map 的更多信息请参考 泛型 和 Maps


    Functions(方法)

    Dart 是一个真正的面向对象语言,方法也是对象并且具有一种 类型, Function。 这意味着,方法可以赋值给变量,也可以当做其他方法的参数。 也可以把 Dart 类的实例当做方法来调用。 详情请参考 Callable classes

    下面是定义方法的示例:

    bool isNoble(int atomicNumber) { 

     return _nobleGases[atomicNumber] != null;

    }

    虽然在 Effective Dart 中推荐 在公开的 APIs 上使用静态类型, 你当然也可以选择忽略类型定义:

    isNoble(atomicNumber) {  

    return _nobleGases[atomicNumber] != null;

    }

    对于只有一个表达式的方法,你可以选择 使用缩写语法来定义:

    bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

    这个 => expr 语法是 { return expr; } 形式的缩写。=> 形式 有时候也称之为 胖箭头 语法。

    注意: 在箭头 (=>) 和冒号 (;) 之间只能使用一个 表达式 – 不能使用 语句。 例如:你不能使用 if statement,但是可以 使用条件表达式 conditional expression

    方法可以有两种类型的参数:必需的和可选的。 必需的参数在参数列表前面, 后面是可选参数。

    Optional parameters(可选参数)

    可选参数可以是命名参数或者基于位置的参数,但是这两种参数不能同时当做可选参数。

    Optional named parameters(可选命名参数)

    调用方法的时候,你可以使用这种形式 paramNamevalue 来指定命名参数。例如:

    enableFlags(bold: true, hidden: false);

    在定义方法的时候,使用 {param1param2, …} 的形式来指定命名参数:

    /// Sets the [bold] and [hidden] flags to the values/// you specify.

    enableFlags({bool bold, bool hidden}) { 

     // ...}

    Optional positional parameters(可选位置参数)

    把一些方法的参数放到 [] 中就变成可选 位置参数了:

    String say(String from, String msg, [String device]) {  

    var result = '$from says $msg'; 

     if (device != null) {   

     result = '$result with a $device'; 

     }  

    return result;

    }

    下面是不使用可选参数调用上面方法 的示例:

    assert(say('Bob', 'Howdy') == 'Bob says Howdy');

    下面是使用可选参数调用上面方法的示例:

    assert(say('Bob', 'Howdy', 'smoke signal') ==    'Bob says Howdy with a smoke signal');

    Default parameter values(默认参数值)

    在定义方法的时候,可以使用 = 来定义可选参数的默认值。 默认值只能是编译时常量。 如果没有提供默认值,则默认值为 null。

    下面是设置可选参数默认值的示例:

    /// Sets the [bold] and [hidden] flags to the values you/// specify, defaulting to false.void enableFlags({bool bold = false, bool hidden = false}) { 

     // ...

    }// bold will be true; hidden will be false

    .enableFlags(bold: true);

    版本问题: 就版本代码可能需要使用一个冒号 (:) 而不是 = 来设置参数默认值。 原因在于 Dart SDK 1.21 之前的版本,命名参数只支持 :。 : 设置命名默认参数值在以后版本中将不能使用, 所以我们推荐你 使用 = 来设置默认值, 并 指定 Dart SDK 版本为 1.21 或者更高的版本。

    下面的示例显示了如何设置位置参数的默认值:

    String say(String from, String msg,    [String device = 'carrier pigeon', String mood]) {  

    var result = '$from says $msg'; 

     if (device != null) {   

     result = '$result with a $device'; 

     }  

    if (mood != null) {    

    result = '$result (in a $mood mood)';  

    }  

    return result;

    }

    assert(say('Bob', 'Howdy') ==    'Bob says Howdy with a carrier pigeon');

    还可以使用 list 或者 map 作为默认值。 下面的示例定义了一个方法 doStuff(), 并分别为 list 和 gifts 参数指定了 默认值。

    void doStuff(    {List<int> list = const [1, 2, 3],    Map<String, String> gifts = const {      'first': 'paper',      'second': 'cotton',      'third': 'leather'    }}) {  

    print('list:  $list'); 

     print('gifts: $gifts');

    }

    Functions as first-class objects(一等方法对象)

    可以把方法当做参数调用另外一个方法。例如:

    printElement(element) { 

     print(element);

    }

    var list = [1, 2, 3];// Pass printElement as a parameter.list.forEach(printElement);

    方法也可以赋值给一个变量:

    var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';

    assert(loudify('hello') == '!!! HELLO !!!');

    Anonymous functions(匿名方法)

    大部分方法都带有名字,例如 main() 或者 printElement()。 你有可以创建没有名字的方法,称之为 匿名方法,有时候也被称为 lambda 或者 closure 闭包。 你可以把匿名方法赋值给一个变量, 然后你可以使用这个方法,比如添加到集合或者从集合中删除。

    匿名函数和命名函数看起来类似— 在括号之间可以定义一些参数,参数使用逗号 分割,也可以是可选参数。 后面大括号中的代码为函数体:

    ([[Typeparam1[, …]]) { 

    codeBlock

    }; 

    下面的代码定义了一个参数为i (该参数没有指定类型)的匿名函数。 list 中的每个元素都会调用这个函数来 打印出来,同时来计算了每个元素在 list 中的索引位置。

    var list = ['apples', 'oranges', 'grapes', 'bananas', 'plums'];

    list.forEach((i) {  

    print(list.indexOf(i).toString() + ': ' + i);

    });

    Lexical closures(词法闭包)

    一个 闭包 是一个方法对象,不管该对象在何处被调用, 该对象都可以访问其作用域内 的变量。

    方法可以封闭定义到其作用域内的变量。 下面的示例中,makeAdder() 捕获到了变量 addBy。 不管你在那里执行 makeAdder() 所返回的函数,都可以使用 addBy 参数。

    /// Returns a function that adds [addBy] to the/// function's argument.Function makeAdder(num addBy) {  return (num i) => addBy + i;}main() {  // Create a function that adds 2.  var add2 = makeAdder(2);  // Create a function that adds 4.  var add4 = makeAdder(4);  assert(add2(3) == 5);  assert(add4(3) == 7);}

    Testing functions for equality(测试函数是否相等)

    下面是测试顶级方法、静态函数和实例函数 相等的示例:

    foo() {}              // A top-level functionclass A {  static void bar() {} // A static method  void baz() {}        // An instance method}main() {  var x;  // Comparing top-level functions.  x = foo;  assert(foo == x);  // Comparing static methods.  x = A.bar;  assert(A.bar == x);  // Comparing instance methods.  var v = new A(); // Instance #1 of A  var w = new A(); // Instance #2 of A  var y = w;  x = w.baz;  // These closures refer to the same instance (#2),  // so they're equal.  assert(y.baz == x);  // These closures refer to different instances,  // so they're unequal.  assert(v.baz != w.baz);}

    Return values(返回值)

    所有的函数都返回一个值。如果没有指定返回值,则 默认把语句 return null; 作为函数的最后一个语句执行。

    Operators(操作符)

    下表是 Dart 中定义的操作符。 很多操作符都可以重载,详情参考 Overridable operators

    描述操作符

    unary postfix    expr++  expr--  ()  []  .  ?.

    unary prefix    -expr  !expr  ~expr  ++expr  --expr 

    multiplicative     *  /  % ~/

    additive   +  -

    shift      <<      >>

    bitwise AND  &

    bitwise XOR  ^

    bitwise OR   |

    relational and type test     >=  >  <=  <  as  is  is!

    equality    ==  != 

    logical AND &&

    logical OR ||

    if null ??

    conditionalexpr1 ? expr2 : expr3

    cascade..

    assignment=  *=  /=  ~/=  %=  +=  -=  <<=  >>=  &=  ^=  |=  ??=

    在使用操作符的时候,就创建了表达式。下面是一些 操作符表达式:

    a++a + b

    a = b

    a == b

    a ? b: c

    a is T

    操作符表格中所列的操作符 都是按照优先级顺序从左到右,从上到下的方式来列出的, 上面和左边的操作符优先级要高于下面和右边的。 例如 % 操作符优先级高于 ==,而 等号 高于 &&。所以下面的 代码结果是一样的:

    // 1: Parens improve readability.if ((n % i == 0) && (d % i == 0))// 2: Harder to read, but equivalent.if (n % i == 0 && d % i == 0)

    警告: 对于有两个操作数的操作符,左边的操作数决定了 操作符的功能。 例如,如果有一个 Vector 对象和一个 Point 对象, aVector + aPoint 使用的是 Vector 对象中定义的 + 操作符。

    Arithmetic operators(算术操作符)

    Dart 支持常用的算术操作符,如下:

    操作符解释

    +加号

    –减号

    -expr负号

    *乘号

    /除号

    ~/除号,但是返回值为整数

    %取模

    示例:

    assert(2 + 3 == 5);

    assert(2 - 3 == -1);

    assert(2 * 3 == 6);

    assert(5 / 2 == 2.5);  // Result is a double

    assert(5 ~/ 2 == 2);    // Result is an integer

    assert(5 % 2 == 1);    // Remainder

    print('5/2 = ${5~/2} r ${5%2}'); // 5/2 = 2 r 1

    Dart 还支持递增、递减前缀 和后缀操作:

    OperatorMeaning

    ++var var = var + 1 (expression value is var + 1)

    var++  var = var + 1 (expression value is var)

    --var  var = var – 1 (expression value is var – 1)

    var--   var = var – 1 (expression value is var)

    示例:

    var a, b;

    a = 0;

    b = ++a;        // Increment a before b gets its value.

    assert(a == b); // 1 == 1

    a = 0;b = a++;        // Increment a AFTER b gets its value.

    assert(a != b); // 1 != 0

    a = 0;b = --a;        // Decrement a before b gets its value.

    assert(a == b); // -1 == -1

    a = 0;b = a--;        // Decrement a AFTER b gets its value.

    assert(a != b); // -1 != 0

    Equality and relational operators(相等相关的操作符)

    下表是和相等操作相关的操作符。

    操作符解释

    ==相等

    !=不等

    >大于

    <小于

    >=大于等于

    <=小于等于

    要测试两个对象代表的是否为同样的内容,使用 == 操作符。(在某些情况下,你需要知道两个对象是否是同一个对象, 使用 identical() 方法。) 下面是 == 操作符工作原理解释:

    如果 x 或者 y 是 null,如果两个都是 null 则返回 true,如果 只有一个是 null 返回 false。

    返回如下函数的返回值 x.==(y)。 (你没看错, 像 == 这种操作符是定义在左边对象上的函数。 你甚至还可以覆写这些操作符。 在后面的 Overridable operators 将介绍如何做。)

    下面是相等关系操作符的 使用示例:

    assert(2 == 2);assert(2 != 3);assert(3 > 2);assert(2 < 3);assert(3 >= 3);assert(2 <= 3);

    Type test operators(类型判定操作符)

    as、 is、 和 is! 操作符是在运行时判定对象 类型的操作符:

    操作符解释

    as类型转换

    is如果对象是指定的类型返回 True

    is!如果对象是指定的类型返回 False

    只有当 obj 实现了 T 的接口, obj is T 才是 true。例如 obj is Object 总是 true。

    使用 as 操作符把对象转换为特定的类型。 一般情况下,你可以把它当做用 is 判定类型然后调用 所判定对象的函数的缩写形式。例如下面的 示例:

    if (emp is Person) { // Type check  emp.firstName = 'Bob';}

    使用 as 操作符可以简化上面的代码:

    (emp as Person).firstName = 'Bob';

    注意: 上面这两个代码效果是有区别的。如果 emp 是 null 或者不是 Person 类型, 则第一个示例使用 is 则不会执行条件里面的代码,而第二个情况使用 as 则会抛出一个异常。

    Assignment operators(赋值操作符)

    使用 = 操作符来赋值。 但是还有一个 ??= 操作符用来指定 值为 null 的变量的值。

    a = value;  // 给 a 变量赋值

    b ??= value; // 如果 b 是 null,则赋值给 b;           // 如果不是 null,则 b 的值保持不变

    还有复合赋值操作符 += 等可以 赋值:

    Conditional expressions(条件表达式)

    Dart 有两个特殊的操作符可以用来替代 if-else 语句:

    condition?expr1:expr2

    如果 condition 是 true,执行 expr1 (并返回执行的结果); 否则执行 expr2 并返回其结果。

    expr1 ?? expr2

    如果 expr1 是 non-null,返回其值; 否则执行 expr2 并返回其结果。

    Cascade notation (..)(级联操作符)

    级联操作符 (..) 可以在同一个对象上 连续调用多个函数以及访问成员变量。 使用级联操作符可以避免创建 临时变量, 并且写出来的代码看起来 更加流畅:

    例如下面的代码:

    Control flow statements(流程控制语句)

    可以使用下面的语句来控制 Dart 代码的流程:

    if and else

    for loops

    while and do-while loops

    break and continue

    switch and case

    assert

    使用 try-catch 和 throw 还能影响控制流程的 跳转,详情请参考 Exceptions

    Switch and case

    Dart 中的 Switch 语句使用 == 比较 integer、string、或者编译时常量。 比较的对象必须都是同一个类的实例(并且不是 其之类),class 必须没有覆写 == 操作符。 Enumerated types 非常适合 在 switch 语句中使用。

    注意: Dart 中的 Switch 语句仅适用于有限的情况, 例如在 解释器或者扫描器中使用。

    每个非空的 case 语句都必须有一个 break 语句。 另外还可以通过 continue、 throw 或 者 return来结束非空 case 语句。

    当没有 case 语句匹配的时候,可以使用 default 语句来匹配这种默认情况。


    Constructors

    定义一个和类名字一样的方法就定义了一个构造函数 还可以带有其他可选的标识符,详情参考Named constructors)(命名构造函数)。 常见的构造函数生成一个 对象的新实例:

    class Point {  num x;  num y;  Point(num x, num y) {    // There's a better way to do this, stay tuned.    this.x = x;    this.y = y;  }}

    this 关键字指当前的实例。

    注意: 只有当名字冲突的时候才使用 this。否则的话, Dart 代码风格样式推荐忽略 this。

    由于把构造函数参数赋值给实例变量的场景太常见了, Dart 提供了一个语法糖来简化这个操作:

    class Point {  num x;  num y;  // Syntactic sugar for setting x and y  // before the constructor body runs.  Point(this.x, this.y);}

    Default constructors(默认构造函数)

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

    Constructors aren’t inherited(构造函数不会继承)

    子类不会继承超类的构造函数。 子类如果没有定义构造函数,则只有一个默认构造函数 (没有名字没有参数)。

    Named constructors(命名构造函数)

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

    class Point {  

    num x; 

     num y; 

    //No Name constructor

    Point(this.x, this.y);

      // Named constructor  

    Point.fromJson(Map json) {   

     x = json['x'];   

     y = json['y'];  

          }

    }

    注意:构造函数不能继承,所以超类的命名构造函数 也不会被继承。如果你希望 子类也有超类一样的命名构造函数, 你必须在子类中自己实现该构造函数。

    Invoking a non-default superclass constructor(调用超类构造函数)

    默认情况下,子类的构造函数会自动调用超类的 无名无参数的默认构造函数。 超类的构造函数在子类构造函数体开始执行的位置调用。 如果提供了一个 initializer list(初始化参数列表) ,则初始化参数列表在超类构造函数执行之前执行。 下面是构造函数执行顺序:

    initializer list(初始化参数列表)

    superclass’s no-arg constructor(超类的无名构造函数)

    main class’s no-arg constructor(主类的无名构造函数)

    如果超类没有无名无参数构造函数, 则你需要手工的调用超类的其他构造函数。 在构造函数参数后使用冒号 (:) 可以调用 超类构造函数。

    常量构造器

    Factory constructors(工厂方法构造函数)

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

    下面代码演示工厂构造函数 如何从缓存中返回对象。

    工厂构造方法

    相关文章

      网友评论

          本文标题:Dart

          本文链接:https://www.haomeiwen.com/subject/vneooqtx.html