これは多くの人にとって興味深いトピックなので、ここでいくつかの光を当てましょう。
次のアプローチをとることができます。
sealed trait Person {
def name: String
}
case class Employee(
override val name: String,
salary: Int
) extends Person
case class Tourist(
override val name: String,
bored: Boolean
) extends Person
はい、フィールドを複製する必要があります。そうしないと、他の問題の中で正しい平等を実装することが単に不可能になります。
ただし、メソッド/関数を複製する必要はありません。
いくつかのプロパティの重複が非常に重要である場合は、通常のクラスを使用しますが、それらはFPにうまく適合しないことに注意してください。
または、継承の代わりにコンポジションを使用することもできます。
case class Employee(
person: Person,
salary: Int
)
val employee = ...
println(employee.person.name)
作曲は有効で健全な戦略であり、同様に検討する必要があります。
また、封印された特性が何を意味するのか疑問に思われる場合は、同じファイルでのみ拡張できるものです。つまり、上記の2つのケースクラスは同じファイルに含まれている必要があります。これにより、徹底的なコンパイラチェックが可能になります。
val x = Employee(name = "Jack", salary = 50000)
x match {
case Employee(name) => println(s"I'm $name!")
}
エラーが発生します:
warning: match is not exhaustive!
missing combination Tourist
これは本当に便利です。これで、他のタイプのPerson
s(人)に対処することを忘れないでください。これは本質的Option
にScalaのクラスが行うことです。
それが問題にならない場合は、それを非封印にして、ケースクラスを独自のファイルにスローすることができます。そして、おそらく作曲と一緒に行きます。