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 支持两种类型的数字:
整数值,其取值通常位于 -253 和 253 之间。
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.
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 named parameters(可选命名参数)
调用方法的时候,你可以使用这种形式 paramName: value 来指定命名参数。例如:
enableFlags(bold: true, hidden: false);
在定义方法的时候,使用 {param1, param2, …} 的形式来指定命名参数:
/// 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 闭包。 你可以把匿名方法赋值给一个变量, 然后你可以使用这个方法,比如添加到集合或者从集合中删除。
匿名函数和命名函数看起来类似— 在括号之间可以定义一些参数,参数使用逗号 分割,也可以是可选参数。 后面大括号中的代码为函数体:
([[Type] param1[, …]]) {
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 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);
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);}
如果你没有定义构造函数,则会有个默认构造函数。 默认构造函数没有参数,并且会调用超类的 没有参数的构造函数。
Constructors aren’t inherited(构造函数不会继承)
子类不会继承超类的构造函数。 子类如果没有定义构造函数,则只有一个默认构造函数 (没有名字没有参数)。
使用命名构造函数可以为一个类实现多个构造函数, 或者使用命名构造函数来更清晰的表明你的意图:
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 来定义 这个构造函数。例如,一个工厂构造函数 可能从缓存中获取一个实例并返回,或者 返回一个子类型的实例。
下面代码演示工厂构造函数 如何从缓存中返回对象。
工厂构造方法
网友评论