私が読んでいる本Javaは、混乱し、受け入れがたい何かを述べています。
あいまいさについて学ぶ
メソッドをオーバーロードすると、あいまいシチュエーション(コンパイラーが使用するメソッドを判別できない状況)を作成するリスクがあります。たとえば、次のオーバーロードされた
computeBalance()
メソッド宣言を考えてみます。_public static void computeBalance(double deposit) public static void computeBalance(double withdrawal)
_
double
という名前のmyDeposit
変数を宣言し、computeBalance(myDeposit);
などのメソッドを呼び出すと、あいまいな状況が発生します。どちらの方法も、呼び出しに完全に一致します。myDeposit
という名前の変数を使用する呼び出しは、deposit
という名前のパラメーターを持つメソッドのバージョンに移動するように見えるが、Java =は変数名に基づく仮定を行いません。computeBalance()
の各バージョンはdouble
を受け入れることができ、Javaは使用するものを想定していません。
これは、メソッドのオーバーロードに関する規則に違反しています。メソッドを同じパラメーターリストでオーバーロードするにはどうすればよいですか?それは不可能ではないですか、それとも私は何かを得ていませんか?そのようなコードを試してコンパイルしたところ、次のエラーが返されます(これは理にかなっています)。
_method computeBalance() is already defined in class XXX
_
これは不十分であり、間違っており、誤解を招くテキストであるとの評価に同意します。
あなたが指摘したように、コンパイラはこれらの宣言だけに基づいて文句を言うでしょう:computeBalance
への呼び出しは必要ありません。一緒に取られたこれらの宣言は誤りです。ここでは(法的な)オーバーロードは行われていません。
テキストからのアイデア
myDeposit
という名前の変数を使用する呼び出しは、deposit
という名前のパラメーターを持つメソッドのバージョンに移動する必要があるように思われるかもしれません...
控えめに言っても奇妙な提案です。作者は、これらの言語がどのように機能するかについてあまり適切ではない仮説的な状況(変数名の一致(誤って宣言されたオーバーロードを解決するため))を引き起こしているようですが、そのように機能しないと言い続けます。ばかばかしい.
価値があるのは、表示できるあいまいなオーバーロードのはるかに良い例です。
それぞれが異なる(クラス)タイプの1つのパラメーターを取る、同じ名前の2つのメソッド。次に、null
を渡してそのメソッド名を呼び出します。コンパイラーは、どのオーバーロードを呼び出すかを認識しません。nullをこれらの型の1つにキャストする必要があります。
明らかに、例の2つのメソッドはあいまいであり、両方のメソッドが同じ名前と同じパラメーターを持っているため、そのコードはコンパイルできません。
public static void computeBalance(double deposit)
public static void computeBalance(double withdrawal)
著者は、上記のようにコンパイルして使用できると主張していません
メソッドをオーバーロードすると、あいまいな状況(コンパイラーがどのメソッドを使用するかを決定できない状況)を作成するリスクがあります。
その後
そして、computeBalance(myDeposit);などのメソッド呼び出しを行うと、あいまいな状況が作成されます。どちらの方法も、呼び出しに完全に一致します。
後で
ただし、Javaは変数名に基づいた仮定を行いません。computeBalance()の各バージョンはdoubleを受け入れる可能性があり、Javaは使用するものを推定しません。
著者があなたが引用したテキストで明確に述べなかった唯一のことは、あいまいなコードはコンパイルできないということです。
個人的には、それが彼の側の間違いであるとは思わず、彼のテキストは誤解を招く、または混乱を招くものだとは思いません。少なくとも"コンパイラはどのメソッドを使用するか決定できない"から明らかです。
著者は、コードを読んだ人が変数とパラメーターの名前に基づいて正しいメソッドを決定できるという架空の状況を作成しているだけで、コンパイラーにはそのような機能がなく、より広いコンテキストを見ることができないと説明しようとしています。
追加のメモと同じように。言語によって、あいまいな呼び出しを表す定義は異なります。たとえば、Javaコンパイラは同じパラメータリストを持つメソッドをオーバーロードできませんが、戻り値の型は異なりますSwiftコンパイラはできます。