オーバーロードにより、メソッドを関数に持ち上げるのが少し難しくなります。
object A {
def foo(a: Int) = 0
def foo(b: Boolean) = 0
def foo(a: Int, b: Int) = 0
val function = foo _ // fails, must use = foo(_, _) or (a: Int) => foo(a)
}
オーバーロードされたメソッドのセットの1つを選択的にインポートすることはできません。
暗黙的なビューを適用して引数をパラメータータイプに適合させようとすると、あいまいさが生じる可能性が高くなります。
scala> implicit def S2B(s: String) = !s.isEmpty
S2B: (s: String)Boolean
scala> implicit def S2I(s: String) = s.length
S2I: (s: String)Int
scala> object test { def foo(a: Int) = 0; def foo(b: Boolean) = 1; foo("") }
<console>:15: error: ambiguous reference to overloaded definition,
both method foo in object test of type (b: Boolean)Int
and method foo in object test of type (a: Int)Int
match argument types (Java.lang.String)
object test { def foo(a: Int) = 0; def foo(b: Boolean) = 1; foo("") }
デフォルトのパラメータを静かに使用できなくすることがあります:
object test {
def foo(a: Int) = 0;
def foo(a: Int, b: Int = 0) = 1
}
個人的には、これらの理由により、オーバーロードを完全に回避することはできません。もっと大きな問題を逃しているように感じます。
[〜#〜] update [〜#〜]
証拠は積み重ねられています。
更新2
更新3
scala> object O { def apply[T](ts: T*) = (); def apply(f: (String => Int)) = () }
defined object O
scala> O((i: String) => f(i)) // oops, I meant to call the second overload but someone changed the return type of `f` when I wasn't looking...
GiladとJason(retroym)が与える理由は、可能な限り過負荷を回避する非常に良い理由です。 Giladの理由は、一般的に過負荷が問題になる理由に焦点を当てていますが、Jasonの理由は、他のScala機能のコンテキストで問題がある理由に焦点を当てています。
Jasonのリストに、オーバーロードは型推論との相互作用が不十分であると付け加えます。考慮してください:
val x = ...
foo(x)
推定されるx
型の変更により、どのfoo
メソッドが呼び出されるかが変わる可能性があります。 x
の-値は変更する必要はありません。推測されるx
のタイプだけです。これはあらゆる種類の理由で発生する可能性があります。
与えられたすべての理由(さらに忘れてしまったことはもう少しあります)のために、メソッドのオーバーロードはできる限り控えめに使用すべきだと思います。
アドバイスは、特にscala向けではありませんが、OO一般的には(これまでのところscalaはOO and functional)の間で最高の組み合わせになるはずです。
Overridingは問題ありません。これは多型の中心であり、OO design。
一方で、オーバーロードはより問題があります。メソッドのオーバーロードでは、どのメソッドが実際に呼び出されるかを見分けるのが難しく、実際に頻繁に混乱の原因になります。また、オーバーロードが実際に必要な理由もめったにありません。ほとんどの場合、問題は別の方法で解決でき、過負荷は臭いであることに同意します。
ここに 記事 があります。これは「オーバーロードは混乱の原因です」と私が言っていることをうまく説明します。 Javaの場合ですが、scalaにも適用されると思います。