我想“锁定”一个类,它是从一个特征扩展而来的。 Scala有可能吗?
例如我有:
trait A {
val boris: String
val john: String
val number: Int
}
class B extends A {
// do something with these values
}
但是我可以确保,如果没有在特征A中声明那些,那么在B类中不会添加新值吗?
感谢您的回答。
答案 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")