在這一步中,你改變的僅是 Dart 的代碼,你可以自己為你新建的類起個名字,當創建這個類的一個實例,隨機選擇一個名字和稱謂,或者你可以提供一個名字和稱謂給構造函數。
## 編輯 piratebadge.dart
在文件的頂部加入 import
import 'dart:html';
?
import 'dart:math' show Random;
piratebadge.dart
## 關鍵信息
- 使用 `show` 關鍵字,你可以只導入你需要的類,方法,和屬性。
- `Random` 提供了一個隨機數的發生器。
加入一個類的聲明在在文件的底部
...
class PirateName {
}
- 這個類的聲明給類提供一個名字
創建一個類級別的 **Random** 實體
class PirateName {
static final Random indexGen = new Random();
}
- `static` 定義類級別的字段,就是說隨機數發生器被所有的類實例共享。
- **Dart** 編輯器強調靜態名字。
- 使用 `new` 調用一個構造函數。
在類中加入兩個成員變量,一個定義 **first name** ,一個定義 **appellation** 。
class PirateName {
static final Random indexGen = new Random();
String _firstName;
String _appellation;
}
- 私有變量用`(_).`強調。**Dart** 沒有 **private** 關鍵字。
在類內創建兩個靜態的 **List** ,提供 **names** 和 **appellations** 兩個集合供選擇。
class PirateName {
...
static final List names = [
'Anne', 'Mary', 'Jack', 'Morgan', 'Roger',
'Bill', 'Ragnar', 'Ed', 'John', 'Jane' ];
static final List appellations = [
'Jackal', 'King', 'Red', 'Stalwart', 'Axe',
'Young', 'Brave', 'Eager', 'Wily', 'Zesty'];
}
- `final` 修飾的變量不能更改。
- 列表是 **Dart** 內置的,使用 **List** 來創建。
-
**List** 類提供 **API** 給列表。
給類提供一個構造函數。
class PirateName {
...
PirateName({String firstName, String appellation}) {
if (firstName == null) {
_firstName = names[indexGen.nextInt(names.length)];
} else {
_firstName = firstName;
}
if (appellation == null) {
_appellation = appellations[indexGen.nextInt(appellations.length)];
} else {
_appellation = appellation;
}
}
}
- 構造函數名和類名相同。
- 參數被包含在花括號 `({ })` 是可選的被命名的參數。
- `nextInt()` 函數得到一個隨機整數從隨機數發生器里。
- 使用方括號 `([ ])` 為列表添加索引。
- 使用 `length` 屬性返回列表中元素的個數。
- 代碼使用隨機數作為列表的索引。
提供一個 `getter` 給私有字段。
class PirateName {
...
String get pirateName =>
_firstName.isEmpty ? '' : '$_firstName the $_appellation';
}
- **Getters** 是一個特別的方法,提供訪問對象的屬性。
- 三元運算符 `?:` 是 `if-then-else` 語句的簡略寫法。
- 字符串插入 `('$_firstName the $_appellation')` 讓我們很容易從其他對象構建字符串。
- 大箭頭 `( => expr; )` 是 `{ return expr; }` 語法的一個簡稱。
重寫 `toString()` 方法。
class PirateName {
...
String toString() => pirateName;
}
- 因為對象實現 `toString()` 方法沒有給很多的信息,很多類重寫 `toString()` 。
- 當你調用 `print(anObject)` 得到字符串,返回值是 `anObject.toString()` 得到的。
- 重寫 `toString()` 在的調試和輸出的時候特別有用。
修改 `setBadgeName()` 方法,使用 **PirateName** 而不是 **String** 。
void setBadgeName(PirateName newName) {
querySelector('#badgeName').text = newName.pirateName;
}
- 代碼調用 **getter** 得到 **PirateName** 作為一個字符串。
更改 `updateBadge()` 基于輸入字段的值生成 **PirateName** 。
void updateBadge(Event e) {
String inputName = (e.target as InputElement).value;
?
setBadgeName(new PirateName(firstName: inputName));
...
}
- 調用構造函數給可選的命名參數提供一個值。
更改 `generateBadge()` 生成一個 **PirateName** 而不是使用 `Anne Bonney`。
void generateBadge(Event e) {
setBadgeName(new PirateName());
}
- 在這種情況下,通過無參數調用構造函數。
## 運行應用
使用 `File > Save All` 保存。
運行應用正確點擊 `piratebadge.html` 并選擇 `Run in Dartium` 。
把你的應用和下面的比較。
在輸入框中輸入。刪除輸入字段。點擊按鈕。

**圖片 5.1** dart4