単一の引数に動的ディスパッチを実装する標準的な方法は、オブジェクト指向ポリモーフィズムです。
abstract class SuperClazz() {
def method(): ReturnType
}
case class SubClazz1() extends SuperClazz {
def method() = {
// stuff
}
}
case class SubClazz2() extends SuperClazz {
def method() = {
// stuff
}
}
// Alternatively just `def func(obj: SuperClazz) =` in this case
def func[T <: SuperClazz](obj: T) =
obj.method()
acase class
を別ので拡張することはできないことに注意してください。通常、 es をまったくcase class
拡張するのは悪いスタイルと見なされます。case class
これを実装するには、おそらくmethod
で抽象化するSuperClazz
必要SuperClazz
があるため、trait
または である必要がありabstract class
ます。
scala での動的ディスパッチのもう 1 つの一般的な代替手段は、パターン マッチです。
sealed abstract class SuperClazz()
case class SubClazz1() extends SuperClazz
case class SubClazz2() extends SuperClazz
def method(obj: SubClazz1) = {
// stuff
}
def method(obj: SubClazz2) = {
// stuff
}
def func(obj: SuperClazz) =
obj match {
case sc1: SubClazz1 => method(sc1)
case sc2: SubClazz2 => method(sc2)
}
スーパークラスまたはトレイトがsealed
(この場合はsealed abstract class SuperClazz()
) の場合、このようなパターン マッチを実装するのが一般的です。シールされたスーパー クラスのオブジェクトを照合する場合、コンパイラは、照合時に実行時エラーが発生しないように、一致するすべての可能性がリストされていることを確認します。いくつかの可能性を指定するのを忘れると、コンパイラは警告を出します。
パターン マッチは複数の引数の動的ディスパッチでも機能しますが、ポリモーフィズムと比較すると、通常はより多くのボイラープレート コードを記述する必要があり、すべてのマッチ ケースを線形にテストしてunapply
関数を呼び出すためのランタイム パフォーマンス コストが大きくなる可能性があります。