Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

FK.

Herança, Downcasting e Upcasting

Recommended Posts

Iaew galera, eu nem programo muito em Java, uso mais PHP e Object Pascal. Mas tenho uma dúvida que vale para qualquer linguagem que tenha suporte completo à orientação a objetos.

 

Seguinte, se eu tenho uma classe A, e nessa classe tenho um método doSomething, uma classe B que extenda essa classe A, herdará o método doSomething, certo? Ou seja

 

public class A {
   public void doSomething() {
       System.out.println("Do something");
   }
}

public class B extends A {
   public void doNothing() {
        System.out.println("Do nothing...");
   }
}

 

Se eu instanciar a classe A e chamar o método doSomething, simplesmente irá executar, e se eu chamar tanto o método doNothing quanto doSometing na classe B, simplesmente executará, certo? Mas se eu quiser chamar o método doSomething da classe A como um objeto da classe B, uso o upcasting e downcasting, assim:

 

A a = new B();
B b = (B)a;
b.doSomething();

 

Mas se eu fizer isso, eu tenho o mesmo efeito:

 

B b = new B();
b.doSomething();

 

pois doSomething é um método herdado da classe A. Então nesse caso eu não ganho nada com isso?

 

Se eu quisesse algo, então a classe A, na verdade deveria ser uma interface ou classe abstrata, onde eu definiria um método que seria implementado em outras diversas classes, certo? Assim:

 

public interface A {
   public void doSomething();
}

public class B implements A {
   public void doSomething() {
       System.out.println("Do something...");
   }

   public void doNothing() {
       System.out.println("Do nothing...");
   }
}

public class C extends B { }

A[] a = new A[2];
a[0] = new B();
a[1] = new C();
for(int i = 0; i < a.lenght; i++) {
   if(a[i] instanceof B) {
       B b = (B)a[i];
       b.doNothing();
   }
   else if(a[i] instanceof C)
       a[i].doSomething();
}

 

Nesse caso, eu não "sei" em tempo de execução quem é B ou C, mas se for B, eu faço downcasting e executo doNothing. Já se for C, não faço downcasting e eu executo doSomething().

 

Enfim, gostaria de saber quando é melhor usar o downcasting e upcasting, pois lá no meu primeiro exemplo, fica meio sem sentido, já nesse segundo exemplo, seria mais usual?

 

Vlw!

 

Edit --

 

Talvez tenha um erro, porque não tenho um compilador/IDE Java aqui para testar os códigos, e não sou especialista em Java.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Então nesse caso eu não ganho nada com isso?

 

Nesse caso em específico não, mas pense no caso da interface Map:

Map map = new HashTable();

 

Se você não quiser usar uma HashTable, mas sim um TreeMap, basta você fazer assim:

Map map = new TreeMap();

 

Essa é a vantagem do polimorfismo... Todos os métodos que precisarem da funcionalidade de um Map podem esperar somente uma instância de uma classe que implementa a interface, sem saber especificamente qual classe está utilizando.

 

Eu também não entendi o que você quis dizer com "Upcasting" e "Downcasting"... Você só pode transformar objetos da classe-mãe em objetos da classe-filha, nunca o contrário.

Por quê?
public class A {
   public void doSomething() {
       System.out.println("Do something");
   }
}

public class B extends A {
   public void doNothing() {
        System.out.println("Do nothing...");
   }
}

Note que é possível você fazer o que você mesmo exemplificou:
A a = new B();
B b = (B)a;
b.doSomething();

 

Entretanto, você não pode fazer:

B b = new B();
A a = (A) b;

 

Enfim, quando usar isso???

Quando você tiver uma interface comum e várias implementações. Isso te garante a flexibilidade de mudar a implementação sempre que quiser, basta que ela implemente a interface. Como o tipo do argumento é o genérico (a interface), nenhuma outra mudança no código é necessária...

Compartilhar este post


Link para o post
Compartilhar em outros sites
Quando você tiver uma interface comum e várias implementações. Isso te garante a flexibilidade de mudar a implementação sempre que quiser, basta que ela implemente a interface. Como o tipo do argumento é o genérico (a interface), nenhuma outra mudança no código é necessária...

 

Nossa, era isso que eu precisava ler. Mais uma vez, fiquei desatento. Esses recursos são sempre bastante utilizados quando temos diversos objetos...

 

Eu também não entendi o que você quis dizer com "Upcasting" e "Downcasting"...

 

Isso são alguns termos usados referentes a tratamento de objetos. De acordo com este artigo, usamos upcasting quando estamos tratando um objeto de uma subclasse como um de uma superclasse. Ou seja, eu fazer isso:

 

A a = new B(); // Upcasting implicíto...

 

É válido, pois estou atribuindo uma instância de uma subclasse, a uma variável de uma superclasse. Agora eu tenho um Objeto B sendo tratado como um objeto A, ou para ser mais específico por exemplo, tenho um cachorro sendo tratado como um animal. Mas e se eu quero tratar esse objeto B como um B, ou ainda, converter de volta esse B para um B? Uso o downcasting, ou seja, converter uma instância de uma subclasse que sofreu upcasting, isso é, que foi tratada como uma superclasse:

 

B b = (B)a;

 

Agora eu estou tratando esse objeto B como sendo um B. Agente usa isso muitas vezes, mas o nome disso é Upcasting e Downcasting. :D

 

Entretanto, você não pode fazer:

B b = new B();
A a = (A) b;

 

Não sei em relação a Java, mas em C# funcionou. Eu testei como A sendo uma interface, e depois sendo uma classe. Os dois não acusaram erro nem durante compilação, nem durante execução. Eu acredito que seja possível, porque eu posso tratar um objeto de uma subclasse como uma superclasse. Se A fosse uma classe Animal e B fosse uma classe Cachorro, então uma instância de cachorro pode ser tratada como um animal, certo? No entanto, se tiver uma instância de animal, e depois tentar tratar esse animal como um cachorro, eu não posso:

 

A a = new A(); // Se fosse uma classe..
B b = (B)a;    // Não acusa erro em compilação, mas em tempo de execução sim.

 

Testei isso em C#...

 

Você só pode transformar objetos da classe-mãe em objetos da classe-filha, nunca o contrário.

 

Henrique, com todo respeito, mas não seria o contrário?

 

Olá? Estou errado no que disse acima? :/

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.