Java에서 다른 반환 유형으로 오버로드?


104

반환 유형을 변경하여 함수를 오버로드 할 수없는 이유는 무엇입니까? Java의 차기 버전에서 변경됩니까?

참고로 C ++에서 가능합니까?



KNU, ​​다른 답변은 일반적인 비언어적 용어로 질문한다는 점에서 다릅니다. 또한 흥미로운 점은 Java JVM이 내부 조작으로 수행 할 수 있도록 지정함으로써 다른 질문에 대한 대답이 더 나아 간다는 것입니다.
J 마못

답변:


157

자바에서는 할 수없고 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에 대한 유효한 입력이기 때문입니다. float f = 7 비교; (7은 float 또는 int입니까?)
NomeN

5
@NomeN 그러나 귀하의 진술에 따르면 func (int i) 및 func (float i)는 컴파일러에서 구별 할 수 없으며 이것이 사실이 아님을 모두 알고 있습니다. 진짜 이유는 Oded (다음 답변 참조)에 의해 제공됩니다-그것은 메서드의 서명에 관한 것입니다. 그리고 btw. 7은 확실히 정수이고 7.0 또는 7f는 float입니다 ;-)
Ta Sas

7
7.0이 아닌 float, 그것은이다 double.
fredoverflow

3
foo();반환 형식이 없으면 모호 하다는 사실이 반드시이를 오버로드로 허용하지 않는 이유는 아닙니다. 모호함을 유발할 수있는 인수 (예 :) foo(null);가 있지만 이것이 본질적으로 오버로드를 무효화하지는 않습니다.
shmosel

48

그 이유는 Java의 오버로드는 서명 이 다른 메소드에만 허용되기 때문입니다 .

반환 형식은 메서드 서명의 일부가 아니므로 오버로드를 구분하는 데 사용할 수 없습니다.

Java 자습서에서 메서드 정의를 참조하십시오 .


4
그런데 왜 반환 형식이 아니라의 일부입니다 서명
andho

51
오 "그냥"! 내가 참조.
andho

3
반환 유형은 메서드 서명의 일부입니다. 클래스 분해를 살펴보십시오.
konmik

2
메서드 오버로딩 규칙이 아닌 @konmik이 아닙니다. 시도 해봐. 동일한 메소드 이름, 동일한 순서의 동일한 매개 변수 유형, 다른 리턴 유형. 컴파일되지 않습니다.
Oded

3
예, 반환 유형이 서명의 일부가 아니기 때문 입니다. 서명은-메서드의 이름 + 매개 변수의 유형과 순서입니다. 내 대답에 제공된 링크를 읽으십시오. "위에 선언 된 메서드의 서명은 calculateAnswer(double, int, double, double)"입니다. ". 반환 유형은 @konmik이 포함되어 있지 않습니다.
Oded

22

Java 5.0 이전에는 메서드를 재정의 할 때 매개 변수와 반환 유형이 모두 정확히 일치해야합니다. Java 5.0에서는 공변 반환 유형이라는 새로운 기능을 도입했습니다. 동일한 서명으로 메서드를 재정의 할 수 있지만 반환 된 객체의 하위 클래스를 반환합니다. 즉, 서브 클래스의 메소드는 수퍼 클래스에서 동일한 시그니처를 사용하여 메소드가 리턴 한 유형의 서브 클래스 인 객체를 반환 할 수 있습니다.


3
처음봤을 때 당황했습니다. 이것이 가능한 이유를 설명해 주셔서 감사합니다!
Dylan Knowles 2013

2
오버로딩과 오버 라이딩은 다릅니다. 오버로딩은 (필수적으로) 상속을 포함하지 않습니다
senseiwu

3
이와 관련이없는 때문에이 대답은 자바 초보자에 대한 오해의 소지가 들릴지 과부하 , 그건 전혀 무시 완전히 다른 일을 -.
azizbekian

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");
    }

}

기본적으로 반환 형식은 계좌로 슬프지만 진실 인수 만, 촬영되지 않는다
알렉산더 밀스

1

컴파일러는 메서드를 구분할 때 반환 형식을 고려하지 않으므로 반환 형식이 다른 경우에도 동일한 서명으로 두 메서드를 선언 할 수 없습니다.


1

메서드를 오버로드하는 동안 반환 유형은 중요하지 않습니다. 모호함이 없는지 확인하기 만하면됩니다!

Java가 호출 할 메소드를 알 수있는 유일한 방법은 인수 목록의 유형을 구별하는 것입니다. 컴파일러가 동일한 이름과 동일한 인수 유형을 가진 두 개의 메서드를 허용하면 어떤 메서드를 호출해야하는지 결정할 방법이 없습니다.


0

컴파일러는 메서드를 구분할 때 반환 형식을 고려하지 않으므로 반환 형식이 다른 경우에도 동일한 서명으로 두 메서드를 선언 할 수 없습니다.

함수 실행을 알고 있다면 함수를 호출 할 때 정의 부분이 실행되고 마침내 return 문이 필요하다는 것을 알게 될 것입니다. 따라서 함수의 전체 정의 뒤에 return이 온다고 말할 수 있습니다. 동일한 이름과 동일한 유형 및 아니오를 가진 더 많은 기능. 함수 이름과 매개 변수가 동일하기 때문에 컴파일러가 호출 할 인수를 어떻게 알 수 있는지 호출 할 때 인수의 수입니다. 처음 호출 할 때 모든 초점은 인수와 함수 이름에 있으며 함수 정의가 완료된 후 마침내 return 문을 처리합니다.

컴파일 시간 오류는 런타임 오류보다 낫습니다. 따라서 Java 컴파일러는 동일한 매개 변수를 가진 동일한 메서드를 선언하면 컴파일러 시간 오류를 렌더링합니다.


수락 된 답변과 어떻게 다른가요? (또한 이유는 그래서 어떻게 적절한 실행 코드를 생성 해, 컴파일러는 호출하는 방법을 알아낼 수 없기 때문에 컴파일 시간 오류입니다)
UnholySheep

-2

실제로 불가능한 방법은 인수 또는 인수의 데이터 유형으로 만 오버로드 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.