これは多くの人にとって興味深いトピックなので、ここで少し光を当てましょう。
次のアプローチをとることができます。
// You can mark it as 'sealed'. Explained later.
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
)
// In code:
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のクラスが行うことです。
それが問題にならない場合は、それを非封印にして、ケースクラスを独自のファイルにスローすることができます。そして、おそらく作曲と一緒に行きます。