有没有一种方法可以禁止在mixin中重写成员?



我定义了一些可堆叠的特征,像这样:

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)。

最新更新