ついにベールを脱いだJavaFX
第7回 クラスを作る
今まで紹介してきたサンプルはすべて,JavaFX Scriptの標準APIを使用して作成してきました。しかし,本格的なアプリケーションを作成するには,標準APIだけではいかんともしがたい部分があります。特にMVCでいうところのM,つまりモデルの部分は標準APIだけで表すには難しい場合が多くあります。
そこで,今回はクラスを自作することに挑戦してみましょう。
クラスの定義
とりあえず,クラスを1つ作ってみましょう。名字と名前を保持するクラスです。
リスト1
class Name {
var firstName: String;
var lastName: String;
function fullname(): String {
return "{firstName} {lastName}";
}
}
クラスの定義はclassで行います。波括弧の中では,アトリビュートと関数の定義を行います。アトリビュートの定義は,変数と同じくvarで行います。Preview SDKまではアトリビュートの定義はattributeだったのですが,JavaFX 1.0で変更されました。
実をいうとこの変更に伴って,アトリビュートという言い方は使わずに,すべて変数として表すことになりました。しかし,単に変数と書いたときにインスタンス変数なのかローカル変数なのか,もしくはスクリプト変数なのか区別しにくいため,この連載では以前からなじみのあるアトリビュートを使い続けることにします。
関数も波括弧の中で定義します。インタープリタ版では関数の実体は波括弧の外で行っていましたが,これも変更されました。
上のNameクラスの場合,firstNameとlastNameという2つのアトリビュートを持ち,いずれも型はStringです。そして,fullnameという関数を持ち,戻り値の型はStringです。
では,このクラスを使ってみましょう。
リスト2
var name = Name {
firstName: "Yuichi"
lastName: "Sakuraba"
}
println("Full Name: {name.fullname()}");
実行結果を以下に示します。
図1
Full Name: Yuichi Sakuraba
アトリビュートにデフォルト値を持たせるには,アトリビュートの定義で値を代入します。アトリビュートにデフォルト値を設定しない場合は表1のようになります。
表1 アトリビュートのデフォルト値
| 型 | デフォルト値 |
|---|---|
| String | "" (null) |
| Integer | 0 |
| Number | 0.0 |
| Duration | 0ms |
| Boolean | false |
| オブジェクト | null |
| 関数 | null |
| シーケンス | [ ] (null) |
Stringとシーケンスにnullと記載しているのは,空文字や要素のないシーケンスがnullと同等に扱われるためです。これも実際に試してみましょう。
リスト3
class Photograph {
var title: String;
var width: Integer;
var height: Integer;
var resizable: Boolean;
var image: Image;
// デフォルト値の代入
var kind: String = "JPEG";
}
var photo = Photograph {};
println("Title: {photo.title}");
println("Width: {photo.width}");
println("Resizable: {photo.resizable}");
println("Image: {photo.image}");
println("Kind: {photo.kind}");
kindアトリビュートだけデフォルト値を設定しました。titleアトリビュートやwidthアトリビュートはデフォルト値はなく,オブジェクト生成時も値を代入していません。このスクリプトを実行すると,次のようになりました。
図2
Title: Width: 0 Resizable: false Image: null Kind: JPEG
この結果からもStringが空文字,Integerが0,そしてBooleanがfalseになることがわかります。また,オブジェクトはnullになります。
次に関数型のアトリビュートを定義してみましょう。関数型のアトリビュートを定義するには,引数と戻り値の型も定義しなくてはなりません。引数の型指定にはコロンはあってもなくてもかまいません。また,関数型のアトリビュートで定義したメソッドをコールするのは,普通の関数をコールするのとまったく変わりません。
リスト4
class Printer {
// 引数,戻り値なし
var reset: function(): Void;
// 引数,戻り値あり
var print: function(String): Boolean;
// こちらでも OK
// var print: function(:String): Boolean;
}
var printer = Printer {
reset: function(): Void {
println("reset");
}
print: function(text: String): Boolean {
println("Print: {text}");
return true;
}
}
printer.print("Hello, World!");
resetアトリビュートは引数がなく,戻り値の型はVoidです。printアトリビュートは引数の型がString,戻り値の型がBooleanになります。実行結果を次に示します。
図3
Print: Hello, World!
varだけでなく,defで変数を定義することも可能です。第3回でdefを使うと,値を一度しか代入できないことを説明しました。それはクラス定義でも同じです。
リスト5
class MathConst {
def pi: Number = 3.1415;
}


