Scala 特征层次结构无法编译
Scala traits hierarchy doesn't compile
在我学习 Scala 的过程中,我创建了以下层次结构:
trait Animal {
val name: String = "Animal"
}
trait HasLegs {
this: Animal =>
val numLegs: Int
}
abstract class Terrestrial extends Animal with HasLegs {
val name: String = "Terrestrial"
}
class Dog(val name: String) extends Terrestrial {
def numLegs = 4
override def toString = {
f"My name is: $name%s. I'm a Dog and I've $numLegs%d legs. I'm from the ${super.name}%s family."
}
}
但是,编译器在 Dog.toString
"super may be not be used on value name" 中抱怨。我做错了什么?
有几个问题,主要是由于在超类中使用 val
,它将其锁定为一个值,而不是可以通过 super
覆盖和访问的东西。没有指定 override
:
也有一些问题
trait Animal {
// in order for super to be called on this it has to be a def
def name: String = "Animal"
}
trait HasLegs {
this: Animal =>
val numLegs: Int
}
abstract class Terrestrial extends Animal with HasLegs {
// this needs to be an override of Animal.name
override def name: String = "Terrestrial"
}
class Dog(override val name: String) extends Terrestrial {
// since the trait specified this as a val, the implementation
// also needs to be a val
val numLegs = 4
override def toString = {
f"My name is: $name%s. I'm a Dog and I've $numLegs%d legs. I'm from the ${super.name}%s family."
}
}
我对内联更改发表了评论。
至于super
不能用在val
上的原因见SI-899
This is the intended behavior, and it was changed so that traits could override vals to be more uniform with classes.
在我学习 Scala 的过程中,我创建了以下层次结构:
trait Animal {
val name: String = "Animal"
}
trait HasLegs {
this: Animal =>
val numLegs: Int
}
abstract class Terrestrial extends Animal with HasLegs {
val name: String = "Terrestrial"
}
class Dog(val name: String) extends Terrestrial {
def numLegs = 4
override def toString = {
f"My name is: $name%s. I'm a Dog and I've $numLegs%d legs. I'm from the ${super.name}%s family."
}
}
但是,编译器在 Dog.toString
"super may be not be used on value name" 中抱怨。我做错了什么?
有几个问题,主要是由于在超类中使用 val
,它将其锁定为一个值,而不是可以通过 super
覆盖和访问的东西。没有指定 override
:
trait Animal {
// in order for super to be called on this it has to be a def
def name: String = "Animal"
}
trait HasLegs {
this: Animal =>
val numLegs: Int
}
abstract class Terrestrial extends Animal with HasLegs {
// this needs to be an override of Animal.name
override def name: String = "Terrestrial"
}
class Dog(override val name: String) extends Terrestrial {
// since the trait specified this as a val, the implementation
// also needs to be a val
val numLegs = 4
override def toString = {
f"My name is: $name%s. I'm a Dog and I've $numLegs%d legs. I'm from the ${super.name}%s family."
}
}
我对内联更改发表了评论。
至于super
不能用在val
上的原因见SI-899
This is the intended behavior, and it was changed so that traits could override vals to be more uniform with classes.