scala中的特性类似于Java或抽象类中的接口。因此,不可能直接从特征中获取实例。但是,我找到了一种实例化特征的方法。这是我做的:
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。在所有这些中,只有特征!完全没有课。
特质如何以这种方式运作?
答案 0 :(得分:6)
此实例化,例如 Java 的Anonymous Classes实例化,因此当new Tweeter with User
实际创建新的匿名实例 for Tweeter with User
匿名类。
并且new Tweeter with User
因此无法编译,因为它失去了name
方法的实现。实际上你需要实现它:
val t = new Tweeter with User {
override def name: String = "hello world"
}
对于new Tweeter with User with DummyUser
,您只需将其说明为new Tweeter with DummyUser
,因为DummyUser
是User
的子类型。
Scala 中有cake pattern,了解如何使用自我类型来实施依赖注入。