0

トレイトから拡張されたクラスを「ロック」したいと思います。Scalaで可能ですか?

たとえば、私は持っています:

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

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

しかし、クラス B では、それらが特性 A で宣言されていない場合、新しい値が追加されないことを保証できますか?

回答ありがとうございます。

4

2 に答える 2

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では、すべてをロックして、ユーザーがこの方法で元のインターフェイスを充実させることができます。

ただし、これが意図したユースケースをカバーしているかどうかはわかりません。継承は提供されません。

于 2013-01-24T20:27:13.110 に答える
0

あなたの例とあなたが実際にやろうとしていることについての私の推測に基づいて、ケースクラスの使用だけを検討したいかもしれません。

ケースクラスを拡張することは一般的に回避されます (試してみると非推奨の警告が表示されると思います)。そのため、機能を追加するためにクラスを拡張したいという人々を防ぐことができます。

例をケース クラスに変換します。

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

次に、値を変更するために拡張する代わりにA、新しいインスタンスを作成します。

val a2 = someOtherA.copy(john="Doe")
于 2013-01-24T21:28:00.717 に答える