2014-11-06 61 views
0

我看到這個代碼:接口的類的對象,鑄造,異常

interface I{}  

class A implements I{} 

class B extends A{} 

class C extends B{} 

class ABC 
{ 

    public static void main(String args[]) 
    { 
     A a=new A(); 
     B b=new B();    
     a=(B)(I)b; //Line 1 
     b=(B)(I)a; //Line 2 
     a=(I)b;  //Line 3 
     I i=(C)a; //Line 4 
    } 
} 

試圖找出

  1. 到即有一個安全的鑄造哪種方式,而不編譯或運行時錯誤
  2. 在什麼情況下鑄件會顯示編譯時錯誤
  3. 在什麼情況下鑄件會顯示運行時異常

任何人都可以解釋我這3個概念嗎?

+0

三年線,它不是*投*引起編譯時失敗 - 它試圖爲'A'類型的變量賦予一個編譯時類型'I'的值... – 2014-11-06 19:20:50

+1

在第二行中,你有一個不是'B'的對象,並且你試圖將其分配給「B」類型的變量。爲什麼在運行時會這樣? – 2014-11-06 19:22:30

+0

因爲我們把它鑄造成B @ david – Gpar 2014-11-06 19:26:01

回答

0

在java中,與類相似的接口是類型。在你的例子中,A類的對象是A類型的,並且是I類型的.B類型的對象是B類型,A類型(子類型)A和I類型.C類型的對象是C類型的,類型(子類型)B,類型(子類型)A和I類型。注意到,對象是兩種類型的類型(兩種類型彼此沒有鏈接,即A和I是獨立類型)以及它們各自超類的子類型。

根據Leskov的替代原則,您可以取代超類型(超級類別)的子類型(子類)。爲了說明看看下面的代碼片段:

公共類InheritanceTest {

public interface I{} 
public class A implements I{} 
public class B extends A{} 
public class C extends B{} 
public class D implements I{} 
public class E{} 

public void method(){ 

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

    D d=new D(); 

    I i=null; 

    i=a;i=b;i=c; 

    a=b; 
    b=c; 
    a=c; 

    a=(A)i;//a=i does not work, A and I are two different types 

    i=d; 
    a=(A)i;//ClassCastException at runtime, D is not an A 

    E e=new E(); 
    //a=(A)e; - this generates a compile time error 

}//method closing 

} //級關閉

演員是必要的,因爲,按照代碼,所有的作爲都是,但所有是不是因爲我可以有一個類D實現了我,但完全不連接到A繼承層次結構。一般來說,當你必須在兩個未連接的類型之間進行轉換時,你需要進行轉換。

注:我編輯的代碼,包括其他類d 注:我已編輯的代碼包含另一個E類

+0

最後但是2行你的意思是=(D)我? @Ironlca – Gpar 2014-11-07 09:04:25

+0

@Gpar,我已經稍微編輯了代碼,我想強調的是D類型的對象,儘管I型不是A型的(因爲A和I是兩個獨立的類型)。在編譯時,這行不會在運行時產生任何錯誤。 – Ironluca 2014-11-07 09:27:34

+0

我可能有點笨,問這個抱歉,爲什麼不能編譯器看到我= D和D不能是A型,然後顯示編譯時錯誤,而不是運行時異常?作爲a =(A)d;是一個編譯時錯誤@Ironluca – Gpar 2014-11-07 09:53:12