Dúvida sobrescrição SCJP 1.6

8 respostas
Cris_Finholdt

Novamente estudando pelo livro… Na parte de sobrescrição de métodos, o livro coloca a seguinte regra:

  • Você não pode sobrescrever um método marcado com static.

Mas aih eu fiz o teste no eclipse com o seguinte código:

class Animal{

public static void eat(){

System.out.println(Animal generico comendo genericamente);

}

}
class Horse extends Animal{

public static void eat(){

System.out.println(Cavalo comendo);

}

}

public class TestAnimals {

public static void main(String[] args) {
	Animal a = new Animal();
	Horse h = new Horse();
	a.eat();
	h.eat();
}

}

Que compila sem erros e mostra a saída:

Animal generico comendo genericamente
Cavalo comendo

Afinal, um método marcado com static pode ou não ser sobrescrito? Se cair uma pergunta dessas no exame, devo responder o q?

8 Respostas

rodrigo.bossini

Um método marcado static não pode ser sobrescrito, mas pode ser redefinido.
Baseado no exemplo que você postou acima, sto implica no seguinte:

public static void main(String[] args) {

Animal a= new Horse();
a.eat();  //em tempo de execução, se o método eat não for static, a jvm executa a versão da classe cavalo. Porém, se o método for static, a versão executada é a da classe Animal.

}
L
rod.attack:
Um método marcado static não pode ser sobrescrito, mas pode ser redefinido. Baseado no exemplo que você postou acima, sto implica no seguinte:
public static void main(String[] args) {

Animal a= new Horse();
a.eat();  //em tempo de execução, se o método eat não for static, a jvm executa a versão da classe cavalo. Porém, se o método for static, a versão executada é a da classe Animal.

}

Por acaso estou estudando este capítulo também... :)

Rod, isto significa que se o código fosse escrito assim:

class Animal{ 
public static void eat(){ 
System.out.println("Animal generico comendo genericamente"); 
} 
} 

class Horse extends Animal{ 
public static void eat(){ 
System.out.println("Cavalo comendo"); 
} 
} 

public class TestAnimals { 

public static void main(String[] args) { 
Animal a = new Animal(); 
Animal h = new Horse(); //Antes estava como Horse h = new Horse()
a.eat(); 
h.eat(); 
} 
}

Ele não iria compilar porque h.eat() estaria chamando o método eat() definido como static na classe Horse?
E uma outra pergunta: Caso o método eat() na classe Animal não fosse marcado como static, h.eat() chamaria o método na classe Animal?

rodrigo.bossini
Lys Marie:
rod.attack:
Um método marcado static não pode ser sobrescrito, mas pode ser redefinido. Baseado no exemplo que você postou acima, sto implica no seguinte:
public static void main(String[] args) {

Animal a= new Horse();
a.eat();  //em tempo de execução, se o método eat não for static, a jvm executa a versão da classe cavalo. Porém, se o método for static, a versão executada é a da classe Animal.

}

Por acaso estou estudando este capítulo também... :)

Rod, isto significa que se o código fosse escrito assim:

class Animal{ 
public static void eat(){ 
System.out.println("Animal generico comendo genericamente"); 
} 
} 

class Horse extends Animal{ 
public static void eat(){ 
System.out.println("Cavalo comendo"); 
} 
} 

public class TestAnimals { 

public static void main(String[] args) { 
Animal a = new Animal(); 
Animal h = new Horse(); //Antes estava como Horse h = new Horse()
a.eat(); 
h.eat(); 
} 
}

Ele não iria compilar porque h.eat() estaria chamando o método eat() definido como static na classe Horse?
E uma outra pergunta: Caso o método eat() na classe Animal não fosse marcado como static, h.eat() chamaria o método na classe Animal?

Um método marcado static, em tempo de execução, é chamado de acordo com o tipo da variável de referência. Ao contrário de um método de instância, que, em tempo de execução, é chamado de acordo com o tipo do objeto.

Ou seja, nesse exemplo h.eat() compilaria e rodaria sem problema nenhum. Por se tratar de um método estático, a JVM executa a versão do método contido na classe da variável de referência.

taaqui

Regras:
1 - Quando um método é declarado como static, diz-se que ele é um método da classe, pertencente a classe.
2 - Estático - algo que não muda; não é dinâmico; constante.
3 - Um método estático não muda o resultado de seu processamento conforme a instância do objeto.
4 - Métodos estáticos não são herdáveis nem sobrescritos.
5 - Se um filho redefine um métodos estático do pai, ele está escondendo o acesso ao método pai. A isto se chama sobreamento ( Shadowing)

Não esquece que isto Animal h = new Horse(); ou isso Animal a = new Animal(); - referencia a classe Animal e a um novo objeto Horse() ou Animal().
Então advinha? métodos static pertencem a classe e não ao objeto certo?
então vai imprimir: Animal genérico comendo genericamente

Isto Horse h = new Horse(); criando um novo Objeto horse, com a referencia da classe Horse.
Então advinha? h.eat(); vai fazer a chamada a classe horse.
então vai imprimir: Cavalo comendo

Me Corrijam se eu estiver errado.

rodrigo.bossini

taaqui:
Regras:
1 - Quando um método é declarado como static, diz-se que ele é um método da classe, pertencente a classe.
2 - Estático - algo que não muda; não é dinâmico; constante.
3 - Um método estático não muda o resultado de seu processamento conforme a instância do objeto.
4 - Métodos estáticos não são herdáveis nem sobrescritos.
5 - Se um filho redefine um métodos estático do pai, ele está escondendo o acesso ao método pai. A isto se chama sobreamento ( Shadowing)

Não esquece que isto Animal h = new Horse(); ou isso Animal a = new Animal(); - referencia a classe Animal e a um novo objeto Horse() ou Animal().
Então advinha? métodos static pertencem a classe e não ao objeto certo?
então vai imprimir: Animal genérico comendo genericamente

Isto Horse h = new Horse(); criando um novo Objeto horse, com a referencia da classe Horse.
Então advinha? h.eat(); vai fazer a chamada a classe horse.
então vai imprimir: Cavalo comendo

Me Corrijam se eu estiver errado.

Exato. Foi o que disse acima.

Lavieri

sei q muita gente ja respondeu, mas tentando ser sucinto…

é possivel redefinir métodos estaticos, mais nunca sobrescrever, o que vc fez não sobrescreveu o método, tanto que se vc fizer uma pequena alteração no seu código

de Animal a = new Animal(); Horse h = new Horse(); a.eat(); h.eat(); paraAnimal a = new Animal(); Animal h = new Horse(); a.eat(); h.eat(); //vera que aqui imprimirar o mesmo que Animal.eat()... pois a referencia h é de um Animal, mesmo ela conendo um Horse //sendo assim não há sobrescrição e sim redefinição

rmala_ti

Não funciona!!!
Se vc tirar a palavra static da classe Animal, a classe Horse herdará este método.

Eu testei e o compilador dá a mensagem: This static method cannot hide the instance method from Animal

Se alguém tiver uma explicação melhor pq não funciona, nos ajude ai.

Abraço.

Lavieri

Não funciona!!!
Se vc tirar a palavra static da classe Animal, a classe Horse herdará este método.

Eu testei e o compilador dá a mensagem: This static method cannot hide the instance method from Animal

Se alguém tiver uma explicação melhor pq não funciona, nos ajude ai.

Abraço.

não funciona pq vc so modificou em uma das classes… esse erro esta falando o seguinte

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

public class Horse extends Animal { public static void eat() {} //iso aqui é impossivel, pois Horse já tem um método public void eat() erdado de Animal //por isso não se pode definir outro estatico, esse foi o erro q vc obteve... }

porem uma classe Horse como abaixo, funcionaria perfeitamente…

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

pronto… agora funciona… e para esse segundo caso

Animal h = new Horse();

onde vc fizesse

h.eat(); ira chamar o eat() de Horse, e não o de Animal, pois mesmo sendo h uma variável Animal, métodos de instancia são chamados sempre de acordo com a instancia alocada na referencia, que no caso é um Horse…

Criado 16 de abril de 2009
Ultima resposta 17 de abr. de 2009
Respostas 8
Participantes 6