Tá... é só colocar um tipo entre parênteses antes da referência e pronto, tá feito o cast. Mas é só isso? Não dá erro? Se dá, quando dá? Se dá, por quê dá?
Ao efetuar um cast, podem ocorrer erros em tempo de compilação e em tempo de execução. Tudo o que o compilador consegue fazer é analisar se o tipo de chegada (a nova referência) e o tipo de partida (aquele que queremos transformar) estão, pelo menos, na mesma árvore de herança.
Ao efetuar um cast, podem ocorrer erros em tempo de compilação e em tempo de execução. Tudo o que o compilador consegue fazer é analisar se o tipo de chegada (a nova referência) e o tipo de partida (aquele que queremos transformar) estão, pelo menos, na mesma árvore de herança.
class Base {}
class Derivada extends Base{}
public class Principal {
public static void main (String[] args) {
Derivada derivada = new Derivada();
Base base = derivada;
}
}
Bem, porque isso funciona? Tá, nós estamos carecas de saber que isso é um upcast. Up o que? Tá viciado em RPG homi? Tá bom, tá bom... Bem devagar.
Downcast: conversão de um tipo genérico para um tipo mais específico.
Upcast: conversão de um tipo mais específico para um tipo genérico.
E aí a gente começa a entender. Upcasting é feito de maneira automática, como a gente já sabe (disso eu tenho certeza). E então, quando ocorre um downcasting?
class Base {}
class Derivada extends Base{
public void teste() {
System.out.println(
"Método da classe Derivada");
}
}
public class Principal {
public static void main(String[] args) {
Base[] arrayBase = {
new Base(),
new Derivada(),
new Base()};
for (Base base : arrayBase) {
if (base instanceof Derivada) {
Derivada derivada = (Derivada) base;
derivada.teste();
}
}
}
}
Consegue entender aquela condicional ali? Bem... é ali que ocorre um downcasting. Até agora, só vimos situações em que as conversões ocorrem perfeitamente bem, sem erros. E quando os erros ocorrem?
Base base = new Base(); Derivada derivada = (Derivada) base;
Bem vindo ao primeiro erro. Veja que a classe Base e a classe Derivada fazem parte da mesma árvore de herança (será que dá pra abstrair o nome das classes?). Então, pelo compilador, passa. Mas quando se executa o trecho de código acima, somos apresentados a uma nova classe: java.lang.ClassCastException. Mas por quê? Ué, a variável de referência base não "aponta" para um objeto do tipo Derivada. Só por isso.
E agora, vamos ao segundo erro.
Base base = new Base(); String string = (String) base;
Nada a ver não é? Esse erro é capturado logo em tempo de compilação, já que o compilador consegue averiguar que Base e String não fazem parte da mesma árvore de herança. Acontece um erro mais ou menos parecido com:
inconvertible types
Para o exame, é necessário saber reconhecer quando é necessário fazer um cast, e que tipos de erro (em tempo de execução e em tempo de compilação) podem ocorrer. Para o dia a dia, é importante fazer um teste do tipo instanceof antes de qualquer downcast.
