Duvida com relação a sobrecarga [SOLUCIONADO]

Olá pessoal,

bom é uma dúvida simples, mas que tá pegando (é do livro da Katy Sierra, página 64):

Dado a classe abaixo:

public class Animal {
public void eat() { }
}

são exemplos de subscrição inválidas:

public void eat(String food) { } // uma sobrecarga válida, e n uma subscrição, porque a lista de argumentos foi alterada.

public String eat() { } //Não é uma subscrição por causa do tipo de retorno, mas tb não é uma sobrecarga pq não há alteração na lista de argumentos.

Tah, minha dúvida é a seguinte:
pra mim todos dois métodos não são sobrecargas; mudou-se a assinatura em ambos, logo deixou de ser uma sobrecarga. Eu penso que para que haja uma sobrecarga deve-se manter a assinatura do método. Ex:

public Horse extends Animal{

public void eat() {
//código diferente do método pai
}

}

Logo os dois métodos anteriores não são sobrecargas…

Estou certo ou errado?

Obrigado.

É isso ai, a sobrecarga se da quando um método na classe filha tem a mesma assinatura do método da classe mãe.

Editado - falei merda :smiley:

É SOBRESCRITA não sobrecarga…

Olha, para voce sobrecarregar um método da classe Pai, voce precisa extende-la na classe Filha.
Dois metodos que mantem suas assinaturas, mais seus argumentos diferentes são métodos sobrecarregados.

class pai
{
    private nomeMae;

    public String Mae()
    {
        return this.nomeMae;
    }
}
class filha extends pai
{
    public String  Mae(String nome)
    {
        this.nomeMae = nome;
    }
}

Espero ter lhe ajudado. Valeu

Olá internetws,

posso entender, de acordo com sua explicação, que para que ocorra uma sobregarca:

  • 1 o tipo de retorno deve ser o mesmo do método da classe pai;
  • 2 o nome do método deve ser o mesmo do método da classe pai;
  • 3 os argumentos podem ser diferentes.

além de que:

  • 4 o modificador de acesso não pode ser menos restritivo que o do método da classe pai;

Mas eu acho q não seja isso…

fiz um teste, veja:

public class Animal {

public Animal(){
    
}

public void eat() {
    System.out.println("Animal eat");
}

}

e:

public class Horse extends Animal {

public Horse() {

}

public void eat(String food) {
    System.out.println("Animal eat: "+food);
}

}

no momento de instância eu chamei o método eat mas apareceram os dois métodos… ou seja, nao ocorreu uma sobrecarga, a JVM entendeu que eat() e eat( String food) são dois métodos diferentes…

Daih eu acho que não… para ser uma sobrecarga a assinatura (incluindo os argumentos) têm que ser iguais…

Alguém poderia ser o minerva nesta dúvida?

Obrigado.

Lendo as respostas agora fiquei com uma duvida… um método que tem a mesma assinatura de um método da classe pai, isso não seria sobrescrita ao inves de sobrecarga?

Você está correto, o pessoal está confundindo sobrecarga com subscrita. Quando não muda a lista de argumentos, acontece uma subscrita.
Só acontece sobrecarga quando muda a lista de argumentos!!

[quote=glauber_rochab]Olá internetws,

posso entender, de acordo com sua explicação, que para que ocorra uma sobregarca:

  • 1 o tipo de retorno deve ser o mesmo do método da classe pai;
  • 2 o nome do método deve ser o mesmo do método da classe pai;
  • 3 os argumentos podem ser diferentes.

além de que:

  • 4 o modificador de acesso não pode ser menos restritivo que o do método da classe pai;

Mas eu acho q não seja isso…

fiz um teste, veja:

public class Animal {

public Animal(){
    
}

public void eat() {
    System.out.println("Animal eat");
}

}

e:

public class Horse extends Animal {

public Horse() {

}

public void eat(String food) {
    System.out.println("Animal eat: "+food);
}

}

no momento de instância eu chamei o método eat mas apareceram os dois métodos… ou seja, nao ocorreu uma sobrecarga, a JVM entendeu que eat() e eat( String food) são dois métodos diferentes…

Daih eu acho que não… para ser uma sobrecarga a assinatura (incluindo os argumentos) têm que ser iguais…

Alguém poderia ser o minerva nesta dúvida?

Obrigado.
[/quote]

Olá você está confundindo as coisas, deixa eu te explicar:

Sobrecarga= Só ocorre quando altera a lista de argumentos, ou seja na verdade a sobrecarga sao apenas dois metodos com o mesmo nome, mas que tem parametros diferentes.
Subscrita= Ocorre quando nao altera a lista de argumentos, ou seja mantem a assinatura da classe super!

Para que ocorra sobrecarga:

[list]Os métodos sobrecarregados devem alterar a lista de argumentos[/list]
[list]Os métodos sobrecarregados podem alterar o tipo de retorno[/list]
[list]Os métodos sobrecarregados podem alterar o modificadore de acesso[/list]

Para que ocorra subscrita:
[list] A lista de argumentos deve coincidir exatamente com o o método subscrito[/list]
[list] O tipo de retorno deve ser o mesmo ou um subtipo do mesmo[/list]
[list] O nível de acesso nao pode ser mais restrito, mais pode ser mais abrangente![/list]
Dentre outras coisas, relacionados a exceções, mas basicamente eh isto!!

Qualquer dúvida, eh so falar!!

Ocorrem as situações de chamadas a métodos sobrecarregados e subscritos

[color=blue]Sempre que você tiver uma classe que herde o método de uma superclasse, poderá subscrever esse método(a menos que,ele tenha sido marcado com final.O beneficio chave subscrição é o recurso de definir um comportamento que seja específico de determinado tipo de subclasse. [/color]

[b]public void eat(String food){ --------------> situação já tanto sobreposta como subscrita, as chamadas serão executadas dependendo de como forem chamadas

}[/b]
A classe Horse tanto sobrepôs quanto subescreveu o método eat(), o mesmo será executado dependendo de como forem chamadas.

[quote=glauber_rochab]Tah, minha dúvida é a seguinte:
pra mim todos dois métodos não são sobrecargas; mudou-se a assinatura em ambos, logo deixou de ser uma sobrecarga. Eu penso que para que haja uma sobrecarga deve-se manter a assinatura do método. Ex:

public Horse extends Animal{

public void eat() {
//código diferente do método pai
}

}

Logo os dois métodos anteriores não são sobrecargas…

Estou certo ou errado?[/quote]
Está errado, vc está confundindo os termos sobrecarga, subscrição e assinatura de métodos.
Na sobrecarga vc deve (obrigatório) alterar a lista de argumentos e o tipo de retorno pode (não obrigatório) ser alterado.
Na subscrição vc não deve (obrigatório) alterar a lista de argumentos e o tipo de retorno não deve (obrigatório) ser alterado, com exceção de um retorno covariante (tipo de retorno que é subtipo do retorno declarado na assinatura do método na superclasse).
A assinatura de método se refere ao modificador de acesso, ao tipo de retorno, ao nome do método além da lista de parâmetros. Uma modificação em qualquer um desses, portanto, significa modificar a assinatura do método. Ela sempre é alterada na sobrecarga pois é obrigatória a mudança da lista de parâmetros. Na subscrição a assinatura do método pode ser alterada por causa dos retornos covariantes e dos modificadores de acessos (desde que menos restritivos). Dê uma olhada na tabela 2-3 na pág. 67, lá vc irá encontrar de forma simples e direta as diferenças entre métodos sobrecarregados e subscritos.

[quote=internetws]Olha, para voce sobrecarregar um método da classe Pai, voce precisa extende-la na classe Filha.
Dois metodos que mantem suas assinaturas, mais seus argumentos diferentes são métodos sobrecarregados.

class pai
{
    private nomeMae;

    public String Mae()
    {
        return this.nomeMae;
    }
}
class filha extends pai
{
    public String  Mae(String nome)
    {
        this.nomeMae = nome;
    }
}

Espero ter lhe ajudado. Valeu[/quote]

Uma forma melhor de se explicar:

class pai
{
    private nomeMae;

    public void Mae()
    {
       //alguma coisa...
    }
}
class filha extends pai
{
    public String Mae(String nome)
    {
        this.nomeMae = nome;
    }
}

Espero ter ajudado. Abração

[quote=internetws][quote=internetws]Olha, para voce sobrecarregar um método da classe Pai, voce precisa extende-la na classe Filha.
Dois metodos que mantem suas assinaturas, mais seus argumentos diferentes são métodos sobrecarregados.

class pai
{
    private nomeMae;

    public String Mae()
    {
        return this.nomeMae;
    }
}
class filha extends pai
{
    public String  Mae(String nome)
    {
        this.nomeMae = nome;
    }
}

Espero ter lhe ajudado. Valeu[/quote]

Uma forma melhor de se explicar:

class pai
{
    private nomeMae;

    public void Mae()
    {
       //alguma coisa...
    }
}
class filha extends pai
{
    public String Mae(String nome)
    {
        this.nomeMae = nome;
    }
}

Espero ter ajudado. Abração[/quote]

Fala kra blz. Só quero fazer algumas observações sobre seu código:

De uma olhada em code conventions, no site da sun:

[list]Nomes de classe devem começar com letra maiscula.[/list]
[list]Nome de metodos devem seguir o padrao camelCase.[/list]

private nomeMae;  

Você esqueceu de definir o tipo do atributo!

this.nomeMae = nome;   

Aqui não ira compilar a classe Filha não herda o atributo nomeMae, pois ele eh private.

Att

É exatamente isso mesmo javadev!!

Valew por ter esclarecido!

:smiley: