余分なオーバーヘッドなしでそれを行う方法は考えられません。ただし、コンパニオンオブジェクトと、いくつかの追加の作業を使用してそれを行うことができます。
object Example {
trait Discovery {
def companion: Discovered
def className: String = companion.className
}
trait Discovered extends Discovery {
override lazy val className = {
println("Getting class name!") // To see how many times we're called
this.getClass.getSuperclass.getName
}
}
class Test extends Discovery {
def companion = Test
}
object Test extends Test with Discovered {}
}
そしてここで、これが機能することがわかります。
scala> val a = new Example.Test
a: Example.Test = Example$Test@17e4c97
scala> val b = a.className
Getting class name!
b: String = Example$Test
scala> val c = a.className
c: String = Example$Test
ただし、コストがかかります。クラスをDiscoveryで装飾するだけでなく、コンパニオンメソッドを実装し、クラスごとにコンパニオンオブジェクト(ちなみに同じ名前である必要はありません)を作成する必要があります。