Uma interessante sobre classes, interfaces

Select two correct statements about the code given below?

class A{}
class B extends A implements E{}	//line 1
class C extends A{}
class D extends B{}
interface E{}
public class Question07 {
	public static void main(String[] args) {
		A a = new D();	//line 2
		C c = new C();	//line 3
		E e = (E)a;	//line 4
		B b = (B)e;	//line 5
	}
}

A. The code compiles without error and runs fine.
B. Compilation error on line 1 because interface E is not yet declared (forward-referencing).
C. Compilation error on line 4 because class A does not implement interface E.
D. The cast on line 4 is mandatory.
E. The cast on line 5 is not mandatory.

Eu to estudando cast de referencias agora. mas naum consigo entender direito. Se alguem quiser explicar essa questaum e pq tanto na linha 4 qnt na 5 o cast é mandatory, vai me ajudar muito.
Valew.

Posso estragar? :smiley:

As respostas corretas são A e D: compila numa boa, e o cast é obrigatório, uma vez que não é possível converter de A para E (uma vez que A não implementa E).

Oi Cv,

A resposta A ??? O Codigo compila mas não roda bem, pois como vc falou dá erro na linha 4 quando roda, não é???

No, no!

O codigo compila E roda numa boa. O cast da linha 4 é mandatório, mas ele está lá :slight_smile:

As respostas corretas são realmente A e D, e existem algumas dicas interessantes para este tipo de casting:
Existem 2 tipos de TYPE, o “Compile-time Type” e o “Runtime Type”, vamos chamar CT e RT respectivamente.
Neste exemplo a variável ‘a’ tem como CT ‘A’ mas tem como RT ‘D’, então a regra geral é, considerando LVALUE = RVALUE, existem 3 casos:

  1º - Se RVALUE "is-a" LVALUE em CP então compila e roda ok, com ou sem typecast.

  2º - Se RVALUE !( "is-a" ) em CP mas "is-a" em RT, então PRECISA de typecast para compilar, e roda ok.

  3º - Se RVALUE !( "is-a" ) em CP e !("is-a") em RT, se fizermos um typecast compila, mas lança uma ClassCastException em RT.

  No exemplo acima :
      a linha 2 está no 1º caso
      a linha 3 está lá só para confundir.
      a linha 4 está no 2º caso, por isso o typecast é obrigatório.
      a linha 5 está também no  2º caso.
  não temos neste exemplo nenhum 3º caso.
  Esta é uma regra simples, fácil de "decorar" e que resolve estas questões sobre typecasting.

[]'s
Claudio Gualberto.

A resposta realmente é A e D.

A correção deste mock diz o seguinte:

First, pay attention to the class hierarchy (B and C are sibling classes!!) Then, there is no such thing as forward-referencing issues when using interfaces declared later in the compilation unit. On line 4, we are dealing with an object whose runtime type is D which implements interface E. The cast is mandatory, though, since the reference type (A) is not assignment compatible with the reference type E. The cast on line 5 is mandatory for the same reasons.