Redefinition e Override

Estou estudando para certificação com o livro da Kathy, e me deparei com o seguinte codigo:

class Animal { static void doStuff() { System.out.print("a "); } } class Dog extends Animal { static void dostuff() { // it's a redefinition, // not an override System.out.print("d "); } public static void main(String [] args) { Animal [] a = {new Animal(), new Dog(), new Animal()}; for(int x = 0; x < a.length; x++) a[x].doStuff(); // invoke the static method } }

E no livro me diz que a saida é a a a, será que alguem pode me explicar por que não é a d a? e O qual é a diferença afinal entre Redefinição e Sobrescrita ?

Obrigado.

Supondo que você tenha errado a assinatura dos métodos…

class Animal { static void doStuff() { System.out.print("a "); } } class Dog extends Animal { static void dostuff() { // it's a redefinition, // not an override System.out.print("d "); } public static void main(String [] args) { Animal [] a = {new Animal(), new Dog(), new Animal()}; for(int x = 0; x < a.length; x++) a[x].doStuff(); // invoke the static method } }

E a variação da caixa não seja proposital (O java é case-sensitive), então:
Os objetos armazenados em “a” são da classe Animal e os objetos Dog são Animal também. Logo, quando você chama o método a[x].doStuff(); você está chamando o método definido na classe Animal.
Se não fosse static, o método pertenceria ao objeto e não a classe (como é o caso), desta forma o método de Dog sobreescreveria o método de Animal.

Certo?

fw

[quote=wagne23]Estou estudando para certificação com o livro da Kathy, e me deparei com o seguinte codigo:

class Animal { static void doStuff() { System.out.print("a "); } } class Dog extends Animal { static void dostuff() { // it's a redefinition, // not an override System.out.print("d "); } public static void main(String [] args) { Animal [] a = {new Animal(), new Dog(), new Animal()}; for(int x = 0; x < a.length; x++) a[x].doStuff(); // invoke the static method } }

E no livro me diz que a saida é a a a, será que alguem pode me explicar por que não é a d a? e O qual é a diferença afinal entre Redefinição e Sobrescrita ?

Obrigado.
[/quote]

Métodos estáticos não podem ser sobrescritos, não existe override, o valor será sempre da Classe Pai más podem sofrer sobrecarga se quizer.

[quote=neoCortex][quote=wagne23]Estou estudando para certificação com o livro da Kathy, e me deparei com o seguinte codigo:

class Animal { static void doStuff() { System.out.print("a "); } } class Dog extends Animal { static void dostuff() { // it's a redefinition, // not an override System.out.print("d "); } public static void main(String [] args) { Animal [] a = {new Animal(), new Dog(), new Animal()}; for(int x = 0; x < a.length; x++) a[x].doStuff(); // invoke the static method } }

E no livro me diz que a saida é a a a, será que alguem pode me explicar por que não é a d a? e O qual é a diferença afinal entre Redefinição e Sobrescrita ?

Obrigado.
[/quote]

Métodos estáticos não podem ser sobrescritos, não existe override, o valor será sempre da Classe Pai más podem sofrer sobrecarga se quizer.[/quote]

O metodo invocado sera chamado de acordo com a Referencia.
Se for uma referencia (e nao objeto) de Dog (Dod d), sera chamado o metodo static de Dog.
Nao necessariamente sera sempre de Animal.

Qdo ocorrer o override (nao static), ai sim: de acordo com o objeto instanciado.

[quote=fabim]
O metodo invocado sera chamado de acordo com a Referencia.
Se for uma referencia (e nao objeto) de Dog (Dod d), sera chamado o metodo static de Dog.
Nao necessariamente sera sempre de Animal.[/quote]

Não entendi. Quando não será sempre de Animal neste caso em que declaramos um Animal?

[quote=Bruno Laturner][quote=fabim]
O metodo invocado sera chamado de acordo com a Referencia.
Se for uma referencia (e nao objeto) de Dog (Dod d), sera chamado o metodo static de Dog.
Nao necessariamente sera sempre de Animal.[/quote]

Não entendi. Quando não será sempre de Animal neste caso em que declaramos um Animal?[/quote]

Se você tirar o ‘static’ dos métodos. Daí a classe Dog faria um ‘override’ no método de ‘Animal’, e imprimiria ‘a d a’.

Mas este exercício em particular está um pouco mal formulado: método estáticos se acessam pela classe, e não por um objeto dela. Ou seja, o certo seria

public static void main(final String[] args) {
    final Animal[] a = { new Animal(), new Dog(), new Animal() };
    for (final Animal element : a)
        Animal.doStuff(); // ou Dog.doStuff();
}

E não existiria confusão. Do jeito que o código está, o compilador até reclama.

The static method doStuff() from the type Animal should be accessed in a static way

Neste caso sera sempre de animal. Mas perceba que pode causar confusao em quem ler, visto que a pessoa que citou que “Métodos estáticos não podem ser sobrescritos, não existe override, o valor será sempre da Classe Pai más podem sofrer sobrecarga se quizer.” nao explicitou que era nesse exemplo.

Alguem poderia pensar que Dog [] d = {Dog(), new Dog(), new Dog()} executaria o static de Animal.

olha so uma dica! isso no inicio eh meio confuso se vc for querer advinhar a resposta baseada no codigo. Se ligue na regra e dai vc encontra a resposta mais facil o que a regra diz?

  • que static nao sao herdados soa redefinidos
  • que o metodos nao static sao subscrito.
  • e quando vc tiver uma referencia para uma subclasse ela so funciona no caso da subscricao
A a = new B();
a.metodo();

so vai chamar metodo se ele foi subscrito na subclasse!

Eu tive que implementar muito e ler N vezes para isso ficar claro e la vai outra dica, estude isso bastante no exame vai aparecer questoes a rodo com essa pegadinha ai, querendo saber o resultado e outras nem compila pq quebra a regra. Eu matei muita questao dela e isso me ajudou pq em outros topicos como api que eh maior decoreba eu nao estava tao seguro. Nos meus resumos que fiz para certifcacacao coloquei N exemplos e expliquei cada um deles com esse assunto se quiser ver dar uma passada no meu blog http://camilolopes.wordpress.com e vai na secao de certificação e veja no post da scjp

flw! abraco e bom estudo :slight_smile:

[quote=fabim]Neste caso sera sempre de animal. Mas perceba que pode causar confusao em quem ler, visto que a pessoa que citou que “Métodos estáticos não podem ser sobrescritos, não existe override, o valor será sempre da Classe Pai más podem sofrer sobrecarga se quizer.” nao explicitou que era nesse exemplo.

Alguem poderia pensar que Dog [] d = {Dog(), new Dog(), new Dog()} executaria o static de Animal.[/quote]

Desculpe acabei me enrolando aqui para responder, na verdade o compilador até chama a atenção nestas situações!!!

Um grande Abraço!!!

Sobre que nem será sempre o do Animal que será chamado é de acordo com a referencia por exemplo:

class Animal{
static void doStuff(){
System.out.println("a");}
}
class Dog extends Animal{
static void doStuff(){
System.out.println("d");
}
}

main

Dog d = new Dog();
d.doStuff();
Animal animal = d;
animal.doStuff();
Dog dog = (Dog) animal;
dog.doStuff();