有没有办法禁止在mixin中覆盖一个成员?

时间:2016-06-28 11:06:06

标签: scala mixins

所以,我定义了一堆可堆叠的特征,如下所示:

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只能有一个实例,并且,如果其中一个mixin试图覆盖它,它就不会工作,因为Bat中定义的那个1}}"特朗普"它。这没关系,除了,我希望"赢得工作"要明确的事情。

任何人都可以想到某种技巧,会尝试覆盖特征中的prefix,而不是从继承它的类中导致编译错误吗?

2 个答案:

答案 0 :(得分:0)

您可以将特征分成两部分并使用explicitly typed self-references,如下所示:

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

答案 1 :(得分:0)

由于traits可以扩展类,因此没有办法禁止traits有一个覆盖前缀的定义,但允许类有一个。

顺便说一句,关于"赢得了工作"部分,我不同意,它按预期工作。我非常确定一个覆盖属性的开发人员完全意识到她很好......压倒她继承的东西。

那么继承类的类呢?

如果你想禁止继承,唯一要做的就是在任何实际上不希望它被进一步覆盖的Trait或Class中标记val / def final(在你的例子中,' d是Foo和Bar)。