Duvida sobre cast

Olá pessoal, essa questão que segue me parece bem confusa gostaria de saber a correta resposta e o porque da resposta, tomara que posssam me ajudar

We have the following organization of classes.

class Parent { }
class DerivedOne extends Parent { }
class DerivedTwo extends Parent { }

Which of the following statements is correct for the following expression.

Parent p = new Parent();
DerivedOne d1 = new DerivedOne();
DerivedTwo d2 = new DerivedTwo();
d1 = (DerivedOne)p;

POSSIBLE ANSWERS: 
1) Illegal both compile and runtime
2) Legal at compile time, but fails at runtime
3)  Legal at compile and runtime 

Espero que possam me ajudar
Atenciosamente

Questoes com codigo que nao tem absolutamente nada a ver com a aplicacao sao relativametne comuns no teste… Muitas vezes ha variavies e classes que sequer sao usadas, entao se voce notar isso, nem perca tempo com elas, concentre-se no codigo “real”.

No caso do teu exemplo acontecer uma RuntimeException ( ClassCastException ), porque voce nao pode subir na hierarquia para fazer casts, pode apenas ir para baixo… por exemplo:

class Pai {}
class Filho extends Pai {}

Voce pode atribuir um objeto do tipo Filho a um objeto do tipo Pai, pois “Pai” eh a super classe de “Filho”, e portando eh garantido que todos os metodos existirao.
Ja o contraio, atribuir um objeto do tipo Pai para um Filho, ira dar erro pois, por ser uma subclasse, 'Filho" pode ter metodos que nao existam em “Pai”, e na hora de chamar tal metodo que soh existe em “Filho”, a JVM nao ira encontrar o metodo na classe “Pai” ( que eh para onde a referencia aponta ) e ira dar exception.

Note que, se voce tirar fora o cast, ira dar erro de compilacao, pois o compilador ve que o cast nao eh possivel e te avisa… mas qdo vc faz o cast, vc esta dizendo “eu sei exatamente o que estou fazendo”.

Ficou meio confufo, mas exemplificando seria assim:

class Pai
{
	public void metodoDoPai() {}
}

class Filho extends Pai
{
	public void metodoDoFilho() {}
}

public class Teste
{
	public static void main(String args[])
	{
		Pai p = new Pai();
		Pai p2 = new Filho(); // OK, Pai eh a super classe de Filho
		Filho f = new Filho();
		// Filho f2 = new Pai(); // ERRO
		
		// p2 aponta para um objeto do tipo Filho,
		// que por ser subclasse de Pai, contem o 
		// metodo metodoDoPai
		p2.metodoDoPai();
		
		// Erro de compilacao, pois Pai nao contem
		// o metodo metodoDoFilho()
		// p2.metodoDoFilho(); // ERRO		
	}
}

Note que, mesmo p2 apontando para uma referencia do tipo Filho, ele ainda eh um objeto “Pai”, portando o compilador sabe quais metodos estao disponiveis.

Acho que eh isso… nao to muito didatico hj hehe

Rafael