我定义了一些可堆叠的特征,像这样:
trait Base {
val prefix: String = ""
def foo = ""
}
trait Foo extends Base {
override def foo = prefix + "/Foo" + ";" + super.foo
}
trait Bar extends Base {
override def foo = prefix + "/Bar" + ";" + super.foo
}
class Bat extends Foo with Bar {
override val prefix: String = "Bat"
}
new Bat().foo
上面返回Bat/Bar;Bat/Foo
,这就是我想要的。现在,问题是,当然,只能有一个prefix
的实例,并且,如果其中一个mixins试图覆盖它,它将不起作用,因为在Bat
中定义的那个"胜过"它。这是可以的,除了,我希望"不会工作"的东西是明确的。
谁能想到某种技巧,这将使尝试重写prefix
在一个特性,而不是在一个类继承它,导致编译错误?
您可以将trait分成两部分,并利用显式类型的自引用,如下所示:
trait Base {
def foo = ""
}
trait Prefix {
val prefix: String = ""
}
trait Foo extends Base { this: Prefix =>
override def foo = prefix + "/Foo" + ";" + super.foo
}
trait Bar extends Base { this: Prefix =>
override def foo = prefix + "/Bar" + ";" + super.foo
}
class Bat extends Prefix with Foo with Bar {
override val prefix: String = "Bat"
}
new Bat().foo
因为trait可以扩展类,所以没有办法禁止trait有一个覆盖的前缀定义,但是允许类有一个。
顺便说一句,关于"不工作"的部分,我不同意,它像预期的那样工作。我很确定重写属性的开发人员完全意识到她…重写她继承的内容
那类继承类呢?
如果你想禁止继承,唯一要做的就是在任何Trait或类中标记val/def final,而这些Trait或类实际上不希望它被进一步覆盖(在你的例子中,就是Foo和Bar)。