trait B { def bId = 1 } trait A { self: B => def aId = 2 } val a = new A with B // The type of a is "A with B", a's value is $anon$1@6ad16c5d
以下内容:
trait User { def name: String } trait DummyUser extends User { override def name: String = "foo" } trait Tweeter { self: User => def tweet(msg: String) = println(s"$name: $msg") } val t = new Tweeter with User // This doesn't compile val t = new Tweeter with User with DummyUser // This does work! // t: Tweeter with User with DummyUser = $anon$1@72976b4 t.tweet("hello") // result is: "foo: hello"
这两段代码都在使用Scala 2.12.在所有这些中,只有特征!完全没有课.
特质如何以这种方式运作?
这个实例化就像Java的 Anonymous Classes实例化一样,所以当新的Tweeter with User它实际上为Tweeter创建了一个带有用户匿名类的新匿名实例.并且新的Tweeter with User不能编译,因为它丢失了name方法的实现.实际上你需要实现它像:
val t = new Tweeter with User { override def name: String = "hello world" }
对于带有DummyUser用户的新Tweeter,您只需要将其声明为带有DummyUser的新Tweeter,因为DummyUser是User的子类型.
在Scala中有一个关于如何使用self类型实现依赖注入的cake pattern.
精彩评论