2012年3月4日日曜日

クラスとインターフェイス

このエントリーをはてなブックマークに追加
Dart はクラスベースのオブジェクト指向言語です。クラス、そしてインターフェイスという、他のオブジェクト指向言語と似た仕組みを持ちます。
  • クラスは他のひとつのクラスを拡張(extends)します。多重継承はできません。
  • クラスの定義で extends を省略したときは、Object を拡張することになります。
  • クラスは複数のインターフェイスを実装(implements)できます。
  • インターフェイスは複数のインターフェイスを拡張(extends)できます。
// 動物インターフェイス
interface Animal {
  void cry();
}

// 犬は動物を継承
class Dog implements Animal {
  void cry() { print("Bark!"); }
}

// 猫も動物を継承
class Cat implements Animal {
  void cry() { print("Mew!"); }
}

// ライオンはネコ科
class Lion extends Cat {
  void cry() { print("Roar!"); }
}

// 動物園で吠えます。
void zoo(Animal a) {
  a.cry();
}

main() {
  zoo(new Dog()); // Bark!
  zoo(new Cat()); // Mew!
  zoo(new Lion()); // Roar!
}
このあたりの仕組みはJavaとほぼ同じですので、Javaに慣れている人はとっつきやすいと思います。

他にも次のような特徴があります。
  • クラスは型変数を extends できません。(class A<T> extends T ということはできない)
  • インターフェイスはデフォルトのファクトリー・クラスを指定できます。
  • インターフェイスには定数の宣言を含むことができます。(static ABC = "ABC";
インターフェイスにデフォルトのファクトリー・クラスが指定できるのは面白い機能です。例としてリストを見てみましょう。DartのListは次のようにインターフェイスとして定義されています。
interface List extends Collection default ListFactory {
...
}
デフォルトのファクトリー・クラスは default キーワードに続けて指定します。

DartのListでは、デフォルトのファクトリー・クラスとして ListFactory クラスが指定されています。デフォルトのファクトリー・クラスが指定されているインターフェイスは、そのままインスタンスを生成することができます。サンプルコード
main() {
  List animals = new List();
  animals.add(new Dog());
  animals.add(new Cat());
  animals.add(new Lion());
  for (Animal a in animals) {
    a.cry();
  }
}


こちらもどうぞ

2012年3月2日金曜日

Dartで変数の型を調べる

このエントリーをはてなブックマークに追加
Dart において変数の型を調べるには、is 演算子を使います。
var a = 1;
print('a is int: ${a is int}'); // true
型Aが型Bから派生して作られている場合は、A is B は true となります。
class B {}
class A extends B {}
main () {
  var a = new A();
  print('a is B: ${a is B}'); // true
  var b = new B();
  print('b is A: ${b is A}'); // false
}
Dart におけるすべての型は Object クラスを継承するので、is Object とすると比較対象がどのような型であっても常に true になります。
print('1 is Object: ${1 is Object}'); // true
print('"a" is Object: ${"a" is Object}'); // true
対象が null であっても is Object の結果は true です。
print('null is Object: ${null is Object}'); // true
したがって、変数がnullかどうかのチェックをするのに is Object は使えません。null と直接比較しましょう。
func(var x) {
  if (x is Object) { /* たとえxがnullであっても、ここは常に実行される。 */ }
  if (x != null) { /* xがnull以外の場合のみ実行される。 */ }
}

Dartをチェックモードで動かす方法

このエントリーをはてなブックマークに追加
この情報は古くなっています。新しい記事を書きましたのでそちらを参照してください。: Dartをチェックモードで動かす方法(更新版)


Dartの実行モードには、プロダクション モードとチェック モードがあります。プロダクション モードでは、変数の代入などについて型による制限はありませんが、チェック モードでは型のチェックがコンパイル時と実行時に行われます。

開発時はチェック モードで動作させ、製品リリース後はプロダクション モードで動かす、といった使い方が想定されます。

そのため何も指定せずにDartスクリプトを実行するとプロダクション モードで動きます。チェック モードで動かす方法は次のとおりです。

Dartboard の場合

画面左上にあるChecked Modeにチェックを入れます。

dart(Dart VM)の場合

--enable_type_checks フラグを指定します。
$ cat test.dart
main() { int a = 'a'; }
$ dart --enable_type_checks test.dart
'test.dart': Failed type check: line 1 pos 18: type 'OneByteString' is not assignable to type 'int' of 'a'.
 0. Function: '::main' url: 'test.dart' line:1 col:18

frogc( Dart-to-JavaScript compiler)の場合

Dart VMと同じ --enable_type_checks フラグ、または --checked フラグを指定します。
$ cat test.dart
main() { int a = 'a'; }
$ frogc --enable_type_checks test.dart
test.dart:1:18: warning: type "dart:core.String" is not assignable to "dart:core.int"
main() { int a = 'a'; }
                 ^^^

Dartium (Chromium with the Dart VM)の場合

Dartium内蔵のDart VMに渡すフラグは、DART_FLAGS環境変数で指定できます。ここにDart VMと同じフラグを指定します。

Ubuntuの場合は次のようになります。
DART_FLAGS='--enable_type_checks' chrome


Dart Editorの場合

スクリプトの実行設定画面の Run in check mode のチェックを入れます。



こちらもどうぞ