2013-10-02 9 views
8

Offensichtlich führt dies zu einem Übersetzungsfehler, weil Stuhl nicht zu Cat verwandt ist:Java: eine Klasse an eine unabhängige Schnittstelle Casting

class Chair {} 
class Cat {} 

class Test { 
    public static void main(String[] args) { 
     Chair chair = new Char(); Cat cat = new Cat(); 
     chair = (Chair)cat; //compile error 
    } 
} 

Warum ist es dann, dass ich nur eine Ausnahme während der Laufzeit erhalten, wenn Ich habe eine Cat-Referenz auf die nicht verwandte Schnittstelle Furniture geworfen, während der Compiler offensichtlich feststellen kann, dass Cat Möbel nicht implementiert?

interface Furniture {} 

class Test { 
    public static void main(String[] args) { 
     Furniture f; Cat cat = new Cat(); 
     f = (Furniture)cat; //runtime error 
    } 
} 
+0

weil Polymorphismus zur Laufzeit passiert. –

+0

aber der Compiler weiß, dass Cat Möbel nicht implementiert, und das zur Laufzeit nicht ändern kann? Ich könnte einen einfachen Punkt vermissen, aber Ihre Antwort hilft mir nicht wirklich – enp4yne

+0

Weil. Auch wenn Cat Möbel nicht direkt umsetzen darf, mag irgendeine Oberklasse von Cat. Und der Compiler beschließt, sich nicht in solche hässlichen Details zu vertiefen, da die Regeln für Schnittstellen ziemlich kompliziert sind. (Danke, Sun.) Und es gibt keine allgemeine Regel *, die * verlangt, dass der Compiler eine unvermeidliche Laufzeitausnahme erkennt (z. B. Division durch Null) - es ist eher ein "Dienst", den es bereitstellt. –

Antwort

12

Der Grund dafür kompiliert

interface Furniture {} 

class Test { 
    public static void main(String[] args) { 
     Furniture f; Cat cat = new Cat(); 
     f = (Furniture)cat; //runtime error 
    } 
} 

ist, dass man sehr gut

public class CatFurniture extends Cat implements Furniture {} 

haben Wenn Sie eine CatFurniture Instanz erstellen, können Sie es zu Cat cat zuweisen und diese Instanz kann sein gegossen zu Furniture. Mit anderen Worten, es ist möglich, dass irgendein Untertyp Cat die Schnittstelle Furniture implementiert.

In Ihrem ersten Beispiel

class Test { 
    public static void main(String[] args) { 
     Chair chair = new Char(); Cat cat = new Cat(); 
     chair = (Chair)cat; //compile error 
    } 
} 

es ist unmöglich, dass einige Cat Subtyp erweitert Chair es sei denn Cat sich von Chair erstreckt.

+4

Es ist nützlich zu beachten, dass, wenn "Cat" als "final" deklariert würde, der Compiler tatsächlich klagen würde (er würde wissen, dass keine Unterklasse von 'Cat'' Furniture' implementieren könnte) Es könnte keine Unterklasse von 'Cat' geben. –

Verwandte Themen