2015-01-03 25 views
5

jeżeli:Casting w Java (interfejs i klasa)

interface I{} 

class A implements I{} 

class B extends A{} 

class C extends B{} 

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

Why a = (B)(I)b; is correct 
but b = (B)(I)a; is false? 

Uważam rzucając się być bardzo mylące, co jest najlepszym sposobem, aby zrozumieć, jeśli mogę w dół lub w górę obsady rzutować obiekt?

+4

Czemu odlewania do 'I' w ogóle? Jeśli usunąłeś całą wzmiankę o 'I' i po prostu miałeś' a = (B) b; 'i' b = (B) a "byłoby to dla ciebie jasne? –

+0

@JonSkeet to pytanie egzaminacyjne java Jestem również bardzo zdezorientowany, dlaczego rzucanie interfejsu "I" – OPK

+0

Oba te są prawidłowe (jak w obu kompilacji i nie zawiedzie w czasie wykonywania). Co konkretnie widzisz, co sprawia, że ​​nie są one kompilowane w Java 7+? – Makoto

Odpowiedz

1

hierarchii klasy wygląda następująco:

C -> B -> A -> I

Object x można rzutować klasy Y, jeśli rodzaj runtime x jest podklasą Y. Lub, innymi słowy, jeśli istnieje ścieżka od typu środowiska wykonawczego x do Y. Przez "typ środowiska wykonawczego" rozumiem typ obiektu (używany podczas konstruowania obiektu) w przeciwieństwie do typu zmiennej (tej z deklaracji zmiennej).

To jest ważne:

b = new B(); 
(B)(I)b; 

obiektu przechowywane w b ma typ B. Został przesłany do I, a następnie z powrotem do B. B jest podklasą obu nich. Przesyłanie do wersji I w rzeczywistości nic nie robi i służy jedynie dezorientacji.

Jednak żaden z nich jest ważny:

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

Będą zarówno niepowodzeniem z wyjątkiem: java.lang.ClassCastException: A cannot be cast to B. a ma typ A, który nie jest podklasą B. Istnieje relacja między A i B, ale jest w przeciwnym kierunku - B jest podklasą A.

celu uzyskania bardziej szczegółowych wyjaśnień zobaczyć tutaj: http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

1

Jedyną rzeczą znaczenie dla odpowiedzi na pytanie w próbce kodowania jest następująca:

class B extends A{} 

Oznacza to, że B jest podklasą A. Podklasy mogą być rzutowane na typy super klasy, ale super klasy nie mogą być rzutowane na typy podklas.

Dlatego nie można rzutować na typ B.

Dlaczego? Myśleć o logice w ten sposób:

enter image description here jest rodzajem Programming_language, ale Programming_language nie jest typem enter image description here