(traitの)defをvalでオーバーライド/実装する
Liftの Loc実装を見ていて気がついた。
scala> trait Hoge { | def fuga:String; | def piyo:String = fuga | } defined trait Hoge scala> val a = new Hoge { | def fuga = "abc" | } a: java.lang.Object with Hoge = $anon$1@1f2a9da scala> val b = new Hoge { | val fuga ="zzz" | } b: java.lang.Object with Hoge = $anon$1@1e3bfb6 scala> a.piyo res3: String = abc scala> b.piyo res4: String = zzz
なるほど、こういうことも出来るわけですか。Scalaの名前空間の仕様、及び、def==val==varみたいな感じの仕様に依っている、のかな?
メソッドpiyoは、そのコンパイル時点では関数としてのfugaしか知らないわけで、そう考えるといろいろ面白いなあ。
ちなみに
def piyo:String = hoge()
はエラーになった。
ちなみに、
scala> trait Hoge { | def fuga():String; | def piyo = fuga() | } defined trait Hoge scala> val a = new Hoge { | def fuga = "abc" | } a: java.lang.Object with Hoge = $anon$1@14a8f44 scala> a.piyo res9: String = abc scala> val b = new Hoge { | val fuga = "zeg" | } b: java.lang.Object with Hoge{def fuga: java.lang.String} = $anon$1@8825a5 scala> b.piyo res10: String = zeg
でもある。
def hoge():String は コンソールの表示でも "hoge: ()String"みたいな型ででてくるから、これをvalで実装しちゃうってのも出来る。
で、気になったので
class Hoge { val a:String = "abc" }
を scalac して jad して見てみると
(略) public String a() { return a; } (略) private final String a = "abc"; (略)
になってた。valへのアクセスはメソッドを通して実施されている。