Javaの異なる戻り値型でオーバーロードしますか?


104

戻り値の型を変更するだけで関数をオーバーロードできないのはなぜですか?それは、Javaの将来のバージョンで変更されますか?

ちなみに、参考までに、これはC ++で可能ですか?



KNU、他の答えは、一般的な非言語固有の用語で質問するという点で異なります。また、興味深いのは、Java JVMが内部の操作で実行できることを指定することで、他の質問の受け入れられた回答がさらに進むことです。
J Woodchuck 2016

回答:


157

Javaではできませんし、C ++ではできません。その理由は、コンパイラーがどの関数を呼び出すかを理解するには、戻り値だけでは十分ではないということです。

public int foo() {...}
public float foo() {..}

...
foo(); // which one?

3
int i = foo()またはfloat f = foo()のようなことをした場合、どちらがどれかを知っていると常に思っていましたが、ステートメントが関数だけの場合、コンパイラはそれを知りません。私はそれを知っています。ありがとう。
nunos

7
@nunos floatであってもf = foo()コンパイラーは、両方のintがfloatの有効な入力であるため、それを理解できません。フロートf = 7を比較します。(7は浮動小数点か整数か?)
NomeN 2010年

5
@NomeNしかし、あなたの発言は、func(int i)とfunc(float i)はコンパイラにとって区別できないことを示唆しています-そして、私たちは皆、これが真実ではないことを知っています。本当の理由はOded(次の回答を参照)によって与えられます-それはメソッドのシグネチャに関するものです。そして、ところで。7は間違いなく整数ですが、7.0または7fは浮動小数点です;-)
Ta Sas

7
7.0はそうfloatではありませんdouble
fredoverflow 2010年

3
foo();戻り値の型がないとあいまいになるという事実は、必ずしもそれをオーバーロードとして許可しない理由ではありません。あいまいさを引き起こす可能性のある引数があります(例:)foo(null);が、それによってオーバーロードが本質的に無効になるわけではありません。
shmosel 2016

48

その理由は、Javaのオーバーロードは、異なるシグネチャを持つメソッドに対してのみ許可されるためです。

戻り値の型はメソッドシグネチャの一部ではないため、オーバーロードを区別するために使用できません。

Javaチュートリアルからのメソッドの定義を参照してください。


4
しかし、なぜ戻り型が署名の
andho

51
ああ、「だから」!そうですか。
andho 2013年

3
戻り値の型はメソッドシグネチャの一部です。クラスの逆アセンブルを調べてください。
konmik 2017

2
それは本当に@konmikではありません-メソッドのオーバーロードのルールによるものではありません。それを試してみてください。同じメソッド名、同じパラメーター型、同じ順序、異なる戻り型。コンパイルしません。
Oded

3
はい、戻り値の型は署名の一部ではありません。シグネチャは-メソッドの名前+パラメータのタイプと順序です。私の回答で提供したリンクを読んでください:「上で宣言されたメソッドのシグネチャは次のとおりです:calculateAnswer(double, int, double, double)」。戻り値の型が含まれていないことを確認してください、@ konmik。
Oded

22

Java 5.0より前では、メソッドをオーバーライドする場合、パラメーターと戻り値の型の両方が正確に一致する必要があります。Java 5.0では、共変戻り型と呼ばれる新しい機能が導入されています。同じシグネチャでメソッドをオーバーライドできますが、返されたオブジェクトのサブクラスを返します。言い換えると、サブクラスのメソッドは、スーパークラスで同じシグネチャを持つメソッドによって返されたタイプのサブクラスであるタイプのオブジェクトを返すことができます。


3
これを最初に見たとき、私は困惑しました。これが可能な理由を説明していただきありがとうございます。
ディランノウルズ2013

2
オーバーロードとオーバーライドは異なります。(必ずしも)オーバーロードには継承は含まれません
センシウウ

3
この答えは、Javaの初心者には誤解を招くように聞こえるかもしれません。なぜなら、それはオーバーロードとはまったく関係がなく、オーバーライドされているからです -完全に別のことです。
アジズベキアン2017年

4

Overloaded 引数も異なる場合、Javaのメソッドは異なる戻り値の型を持つ場合があります。

サンプルコードを確認してください。

public class B {

    public String greet() {
        return "Hello";
    }

    //This will work
    public StringBuilder greet(String name) {
        return new StringBuilder("Hello " + name);
    }

    //This will not work
    //Error: Duplicate method greet() in type B
    public StringBuilder greet() {
        return new StringBuilder("Hello Tarzan");
    }

}

基本的に戻り値の型は考慮されず、引数のみが考慮されますが、悲しいですが真実です
Alexander Mills

1

コンパイラーはメソッドを区別するときに戻り値の型を考慮しないため、戻り値の型が異なっていても、同じシグニチャーを持つ2つのメソッドを宣言することはできません。


1

メソッドのオーバーロード中は、戻り値の型は関係ありません。あいまいさがないことを確認するだけです!

Javaが呼び出すメソッドを知る唯一の方法は、引数リストのタイプを区別することです。コンパイラーが同じ名前と同じ引数タイプの2つのメソッドを許可した場合、どのメソッドを呼び出すかを決定する方法はありません。


0

コンパイラーはメソッドを区別するときに戻り値の型を考慮しないため、戻り値の型が異なっていても、同じシグニチャーを持つ2つのメソッドを宣言することはできません。

関数の実行を認識している場合は、関数を呼び出すときに定義部分が実行され、最後にreturnステートメントが必要であることを認識します。そのため、returnは関数全体の定義の後に来ると言えます。同じ名前、同じタイプ、noの関数が他にもあります。関数名とパラメーターが同じであるため、呼び出し時のコンパイラーはどの引数が呼び出されるかをどのように認識するかを呼び出し時に。最初に呼び出すとき、すべての焦点は引数と関数名になり、関数定義の完了後、ようやくreturnステートメントを扱います。

コンパイル時エラーは実行時エラーよりも優れています。したがって、同じパラメーターを持つ同じメソッドを宣言すると、Javaコンパイラーはコンパイラー時間エラーをレンダリングします。


これは受け入れられた回答とどう違うのですか?(また、それがコンパイル時エラーである理由は、コンパイラーが呼び出すメソッドを
判別

-2

あなたが引数なしで、または引数のデータ型でのみオーバーロードできるように、実際には不可能ではありません

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.