我是Scala的新手,来自Java,我只是阅读有关特征的内容。经常提到的一件事是,特征不是(不能“赢得”)具有构造函数参数。我很想知道是否有理由这样做。
从很久以前的数学/计算机科学背景来看,我想知道这是不可避免的结果,因为某些语言设计决定,还是有意识地决定避免一些继承/混合问题?
希望有人知道,因为事实背后可能会有一些有趣的东西。
答案 0 :(得分:8)
其他答案描述了语言;我怀疑你的问题可能真的是“它为什么以这种方式设计”。
我认为它源于在扩展多种特征时会出现的尴尬和冗长,特别是在覆盖和类型以及各种混合策略的情况下。
蛋糕模式通常会导致各种特征以混合类中完全不可见的方式相互提供缺失的位。混合可以是双向的,使用self-types。因此,从特征构造一个类对于编译器来说可能是一个非常混乱的业务。 Scala经常将编译器设计和实现的简单性换成简单的语言使用和代码减少,这当然是一个很好的例子。
因此,尽管可能存在简单的分层情况,其中具有构造函数可能是有用且充分的,但对于更困难的非分层场景,它几乎肯定必须是其他机制的冗余。
答案 1 :(得分:2)
Traits没有构造函数参数,因为无法构造traits。给定任何特征T
,不可能实例化任何类型为T
的对象。你可以用val覆盖trait defs,所以
trait Foo {
def bar: String
}
class Baz(override val bar: String) extends Foo
您无法直接构造它们,因为new MyTrait {}
实际上是new Object with MyTrait {}
答案 2 :(得分:1)
答案是:那就是现在的Scala。
但未来情况可能并非如此:特质参数可以取代早期的初始化器。 (参见Martin Odersky最近的Scala Days演示文稿第34页) Scala: Where It Came From & Where It is Going
答案 3 :(得分:0)
Trait是Java接口的模拟。主要区别在于trait可以为其方法设置默认实现。
所以Java接口不能有构造函数,因此Scala特征
答案 4 :(得分:0)
Scala 3将允许特征参数。这是docs
的示例trait Greeting(val name: String) {
def msg = s"How are you, $name"
}
class C extends Greeting("Bob") {
println(msg)
}