menu
書いてる野郎
orebike@gmail.com
Ruby の Mixin みたいなやつ、Java の インタフェースに実装を取り付けたようなもの
機能を滑りこませたいクラスに with
キーワードを使ってズラズラ書くと何個でもつけることができる。
class Hoge with Piyo with Fuga { }
特異オブジェクトのようにクラスから生成されるオブジェクト全てではなくある特定のオブジェクトのみに滑りこませることもできる
var hoge:Hoge = new Hoge() with Piyo
トレイトでむき出しになっている部分は クラスのコンストラクタに相当し、with したクラスが new された時に実行される。 このへんは JavaScript の new のようである。 しかしクラスのコンストラクタのように外部からパラメータを取ることはできない。
複数 with していた場合は左側から順に実行される。
複数 with でトレイト間でメソッド名が被ってしまった場合は with されているクラスは override
キーワードを使って実装しなおさないといけない。
クラス内部からトレイトのメソッドを呼ぶには
var hoge:Int = super.hogehoge(123)
このように super キーワードで呼び出す。つまりこれは継承されているものもひっくるめて全部の中からコレっていうことで選ぶということ。
複数 with していた場合は
var hoge:Int = super[Piyo].hogehoge(123)
このように super に続きブラケットでトレイト名を指定してやると名指しで使えるようになる。
逆はできない?つまりトレイト内部で継承先クラスを呼ぶ・・・。これはUIを工夫するしかないか。
トレイトは new することもできる。
trait Hoge { } var aaa = new Hoge{}
括弧の形状が普通のクラスと違うが、この括弧が無名クラスを表していてそれに対して with しているという扱いになっている。
トレイト はクラスを継承(宣言)することができ、内部でメソッド等を使用(宣言)することができる。
trait Hoge extends Piyo { }
これを記述することで、トレイトは with 先のクラスを extends しているクラスに限定することができる。
記述はトレイトが親クラスを継承しているように見えるが、それがOKならどんなクラスでもいくつでもOKということになるので、これはあくまでも「宣言」であり実際には with されて初めて効果を発揮する。ということでこれはまだ「宣言」であって実装じゃないんですよということで、親クラスのメソッドを使う場合はそのメソッド自体を
trait Hoge extends Piyo { abstruct override def aaa = { super.fuga } }
という風に宣言しなければならない