Sobrecarga com tipo de retorno diferente em Java?


104

Por que não é possível sobrecarregar uma função apenas alterando o tipo de retorno? Isso mudará em uma versão futura do Java?

A propósito, apenas para referência, isso é possível em C ++?


1
possível duplicata de sobrecarga
KNU

KNU, ​​a outra resposta difere porque faz a pergunta em termos gerais, não específicos da linguagem. Também interessante é que a resposta aceita de outra pergunta vai além, especificando que o Java JVM permite que isso seja feito com manipulação de componentes internos.
J Woodchuck de

Respostas:


157

Você não pode fazer isso em Java e não pode fazer em C ++. A justificativa é que o valor de retorno sozinho não é suficiente para o compilador descobrir qual função chamar:

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

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

3
Sempre pensei que, se fizéssemos algo como int i = foo () ou float f = foo (), ele saberia qual, mas se a instrução fosse apenas a função que ela, o compilador não saberia. Eu entendo. Obrigado.
nunos

7
@nunos mesmo se fosse float f = foo (), o compilador não seria capaz de descobrir porque ambos um int seria uma entrada válida para um float. Compare float f = 7; (é 7 um float ou int?)
NomeN

5
@NomeN Mas sua declaração sugere que func (int i) e func (float i) seriam indistinguíveis para o compilador - e todos nós sabemos que isso não é verdade. A verdadeira razão é dada por Oded (veja a próxima resposta) - é sobre a assinatura do método. E, aliás. 7 é definitivamente um número inteiro enquanto 7.0 ou 7f é flutuante ;-)
Ta Sas

7
7.0 não é float, é double.
fredoverflow

3
O fato de que foo();sem um tipo de retorno seria ambíguo não é necessariamente um motivo para rejeitá-lo como uma sobrecarga. Existem argumentos que podem causar ambigüidade (por exemplo foo(null);), mas isso não torna a sobrecarga inerentemente inválida.
shmosel

48

A razão é que sobrecargas em Java são permitidas apenas para métodos com assinaturas diferentes .

O tipo de retorno não faz parte da assinatura do método, portanto, não pode ser usado para distinguir sobrecargas.

Consulte Definindo métodos a partir dos tutoriais Java.


4
Mas por que o tipo de retorno não faz parte da assinatura
andho

51
oh "só porque"! Entendo.
andho

3
O tipo de retorno é uma parte da assinatura do método. Basta olhar para a desmontagem da classe.
konmik

2
Realmente não é @konmik - não pelas regras de sobrecarga de método. Tente. Mesmo nome de método, mesmos tipos de parâmetro na mesma ordem, diferentes tipos de retorno. Não vai compilar.
Oded

3
Sim, pois o tipo de retorno não faz parte da assinatura . A assinatura é - o nome do método + os tipos e a ordem de seu parâmetro. Leia o link que forneci em minha resposta: "A assinatura do método declarado acima é: calculateAnswer(double, int, double, double)". Veja se o tipo de retorno não está incluído, @konmik.
Oded

22

Antes do Java 5.0, quando você substitui um método, os parâmetros e o tipo de retorno devem corresponder exatamente. No Java 5.0, ele introduz um novo recurso chamado tipo de retorno covariant. Você pode substituir um método com a mesma assinatura, mas retorna uma subclasse do objeto retornado. Em outras palavras, um método em uma subclasse pode retornar um objeto cujo tipo é uma subclasse do tipo retornado pelo método com a mesma assinatura na superclasse.


3
Fiquei perplexo quando vi isso pela primeira vez. Obrigado por explicar porque isso é possível!
Dylan Knowles

2
sobrecarregar e substituir são diferentes. A sobrecarga não envolve (necessariamente) herança
senseiwu

3
Essa resposta pode soar enganosa para um novato em Java, porque não é relevante com a sobrecarga em tudo, ele está substituindo - completamente outra coisa.
azizbekian

4

Overloaded os métodos em java podem ter diferentes tipos de retorno, visto que o argumento também é diferente.

Confira o código de amostra.

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

}

basicamente o tipo de retorno não é levado em consideração, apenas os argumentos, tristes, mas verdadeiros
Alexander Mills

1

O compilador não considera o tipo de retorno ao diferenciar métodos, portanto, você não pode declarar dois métodos com a mesma assinatura, mesmo se eles tiverem um tipo de retorno diferente.


1

O tipo de retorno não importa ao sobrecarregar um método. Precisamos apenas garantir que não haja ambigüidade!

A única maneira de o Java saber qual método chamar é diferenciando os tipos da lista de argumentos. Se o compilador permitisse dois métodos com o mesmo nome e os mesmos tipos de argumento, não haveria como determinar qual deveria chamar.


0

O compilador não considera o tipo de retorno ao diferenciar métodos, portanto, você não pode declarar dois métodos com a mesma assinatura, mesmo se eles tiverem um tipo de retorno diferente.

Se você está ciente da execução da função, então você deve estar ciente de que quando chamamos uma função, a parte da definição executa e, por fim, exigimos a instrução de retorno, portanto, podemos dizer que o retorno vem após a definição inteira da função, é por isso que se houver dois ou mais funções com o mesmo nome e com o mesmo tipo e não. de argumentos, então, no momento da chamada, como o compilador saberá sobre qual deles deve ser chamado, porque o nome da função e os parâmetros são os mesmos. No momento da chamada, primeiro todo o foco estará nos argumentos e no nome da função e, após a conclusão da definição da função, finalmente lidamos com a instrução de retorno.

Compile Time Error é melhor do que Run Time Error. Portanto, o compilador java renderiza o erro de tempo do compilador se você declarar o mesmo método com os mesmos parâmetros.


Como isso difere da resposta aceita? (Além disso, é um erro em tempo de compilação porque o compilador não consegue descobrir qual método chamar, então como ele deve gerar o código executável adequado)
UnholySheep

-2

não, não é realmente possível dessa forma, você só pode sobrecarregar por nenhum dos argumentos ou tipo de dados dos argumentos

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.