15

Scala で同じトレイトを継承する 2 つの異なるクラスのメソッドを定義するには、2 つの方法があります。

sealed trait Z { def minus: String }
case class A() extends Z { def minus = "a" }
case class B() extends Z { def minus = "b" }

代替手段は次のとおりです。

sealed trait Z { def minus: String = this match {
    case A() => "a"
    case B() => "b"
}
case class A() extends Z
case class B() extends Z

最初のメソッドはメソッド名を繰り返しますが、2 番目のメソッドはクラス名を繰り返します。

コードが分かれているので、1番の方法が一番使いやすいと思います。ただし、複雑なメソッドには2番目のメソッドを使用することが多いため、たとえば次のように、追加の引数を非常に簡単に追加できます。

sealed trait Z {
  def minus(word: Boolean = false): String = this match {
    case A() => if(word) "ant" else "a"
    case B() => if(word) "boat" else "b"
}
case class A() extends Z
case class B() extends Z

これらの慣行の他の違いは何ですか? 2 番目のアプローチを選択した場合、バグが発生する可能性はありますか?

編集: 私はオープン/クローズの原則を引用しましたが、新しいケースクラスに応じて関数の出力だけでなく、コードのリファクタリングのために入力も変更する必要がある場合があります。最初のものよりも良いパターンはありますか? 最初の例に前述の機能を追加すると、入力が繰り返される見苦しいコードが生成されます。

sealed trait Z { def minus(word: Boolean): String  ; def minus = minus(false) }
case class A() extends Z { def minus(word: Boolean) = if(word) "ant" else "a" }
case class B() extends Z { def minus(word: Boolean) = if(word) "boat" else "b" }
4

4 に答える 4