|
クラスと変数とメソッドの話 オブジェクト指向の短いサンプルというとどうしてもアルゴリズミックな話題になってしまいますが、 ここで使うクラス「Moroqueue」とはこのよーなものです。 というのを最初に概略だけ紹介してみます。
package require Itcl
class Moroqueue {
variable Q
constructor {args} {
set Q $args
}
method enqueue e {
if {[set p [lsearch -exact $Q $e]] != -1} {
set Q [lreplace $Q $p $p]
}
lappend Q $e
}
method dequeue {} {
set r [lindex $Q 0]
set Q [lreplace $Q 0 0]
return $r
}
method get {} { return $Q }
}
Moroqueue mo 5 6 7
puts [mo get]
mo enqueue 4; puts [mo get]
mo enqueue 8; puts [mo get]
mo dequeue; puts [mo get]
mo enqueue 7; puts [mo get]
mo dequeue; puts [mo get]
mo enqueue 8; puts [mo get]
mo dequeue; puts [mo get]
# end.
[incr Tcl]のOO文法でもやはり基本はクラスの定義で、 これはclassコマンドで大きくブロックを囲むことで行えます。 で、このブロックにつける名前、 つまりclassコマンドの最初の引数がクラス名と呼ばれるものです。 この例では、Moroqueueという名前のクラスをひとつ定義しています。 クラスのブロック内で共通して使える変数、C++ではメンバ変数、 Javaではインスタンス変数と呼ばれますが、は、 variableコマンドで宣言・定義することができます。 (以後インスタンス変数と呼ぶことにします) variable profiles variable filename "untitled"2番目のように、宣言と同時に値を代入することもできます。 クラスが「インスタンス化」(↓)されるときに実行される特別なプロシージャを コンストラクタと言います。 コンストラクタはprocの代わりにconstructor コマンドを使うほかはTcl言語のプロシージャと全く同じです。 コンストラクタには、普通インスタンス変数の初期化処理を書いておきます。 さてクラス内では、クラスに属するプロシージャ、という意味で、 標準Tclのprocは使わずに、 代わりにmethodというコマンドを使います。 methodコマンドで定義した、 クラスに属するプロシージャのことをメソッドと言います。 メソッドの書き方自体は、Tcl言語の構文と同じです。 プロシージャの中でローカルな変数を使うことができるほか、 インスタンス変数も、特に断りなく勝手に使うことが出来ます。
method enqueue e {
if {[set p [lsearch -exact $Q $e]] != -1} {
set Q [lreplace $Q $p $p]
}
lappend Q $e
}
クラスというのは単にいくつかの変数といくつかのメソッドでデータ構造というか枠組みを定義しただけのものなので、 実際にそれを使うにはインスタンス化 (「オブジェクト」をつくること) という処理を行わせる必要があります。 インスタンス化は、[incr Tcl]ではこのようにして行います。 Moroqueue mo 5 6 7つまり、「Moroqueue」というクラスを定義することは、 [incr Tcl]では「Moroqueue」 というTclコマンドを作ることでもある、という点が一点、 そのMoroqueueというコマンドは Moroqueueクラスのインスタンス化を行うコマンドだという点が一点、 Moroqueue インスタンス名 引数...インスタンス名は、[incr Tcl]のマニュアルなどでは オブジェクトハンドル と呼ばれていることもあります。これはインスタンスを一意の識別できる名前なら何でもOKです。 その後ろの引数の並びは、 そのままMoroqueueクラスのconstructorで定義されたコンストラクタがあれば、 それに渡され、コンストラクタの定義通り処理が行われます。
mo enqueue 4これが[incr Tcl]でのメソッドの呼び出しの最も簡単な例です。 つまりインスタンス名にメソッド名をつけ、 あればその後ろに引数を空白で区切って並べていくという、 Tkウィジェットのウィジェットコマンドと全く同じやり方が通用します。 |