Scala/トレイト

Scala/トレイト

Ruby の Mixin みたいなやつ、Java の インタフェースに実装を取り付けたようなもの

作り方

trait キーワードを使って普通にクラスのように書く

trait Hoge {
    def aaa = {
      "aaa"
    }
}

使い方

機能を滑りこませたいクラスに 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 しているという扱いになっている。

with先の制限

トレイト はクラスを継承(宣言)することができ、内部でメソッド等を使用(宣言)することができる。

trait Hoge extends Piyo {
}

これを記述することで、トレイトは with 先のクラスを extends しているクラスに限定することができる。

記述はトレイトが親クラスを継承しているように見えるが、それがOKならどんなクラスでもいくつでもOKということになるので、これはあくまでも「宣言」であり実際には with されて初めて効果を発揮する。ということでこれはまだ「宣言」であって実装じゃないんですよということで、親クラスのメソッドを使う場合はそのメソッド自体を

trait Hoge extends Piyo {
  abstruct override def aaa = {
    super.fuga
  }
}

という風に宣言しなければならない

scala/trait.txt · 最終更新: 2017-01-11 10:53 by ore