Scala:锁定扩展类

时间:2013-01-24 20:07:33

标签: scala inheritance locking traits

我想“锁定”一个类,它是从一个特征扩展而来的。 Scala有可能吗?

例如我有:

trait A {
val boris: String
val john: String
val number: Int
}

class B extends A {
 // do something with these values
}

但是我可以确保,如果没有在特征A中声明那些,那么在B类中不会添加新值吗?

感谢您的回答。

2 个答案:

答案 0 :(得分:4)

你不能。

但是,如果您只是将特征标记为已密封并提供默认实施:

sealed trait A { val boris: String }
final class B(val boris: String) extends A {}

然后人们可以自由创建隐式值类,使其看起来像添加了新功能(除非没有实际创建类):

implicit class MyB(val underlying: B) extends AnyVal {
  def sirob = underlying.boris.reverse
}
(new B("fish")).sirob   // "hsif"

如果你想让它们在编译时保持直接(虽然不是运行时),你也可以让类将一个类型参数作为标记:

sealed trait A[T] { val boris: String }
final class B[T](val boris: String) extends A[T] {}

implicit class MyB(val underlying: B[Int]) extends AnyVal {
  def sirob = underlying.boris.reverse
}
(new B[Int]("fish")).sirob   // "hsif"
(new B[Char]("fish")).sirob  // error: value sirob is not a member of B[Char]

所以你可以 - 尤其是2.10 - 只需锁定所有内容,让用户以这种方式丰富原始界面。

我不确定这是否涵盖了您的预期用例;它不提供任何继承。

答案 1 :(得分:0)

根据您的示例以及我对您实际尝试的内容的猜测,您可能需要考虑使用案例类。

通常可以避免扩展案例类(我认为如果您尝试,它会吐出弃用警告),这样可以防止人们扩展您的类以添加功能。

将您的示例翻译成案例类:

case class A (boris: String, john: String, number: Int)

然后,您只需创建一个新实例,而不是扩展A来更改其值,例如

val a2 = someOtherA.copy(john="Doe")