2014-11-06 8 views
0

Я видел этот код:Interface-класс объект, литье, Exception

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

Для третьей линии, это не * литой *, что вызывает сбой во время компиляции - это попытка присвоить значение типа компиляции 'I' переменной типа' A' ... –

+1

В строке 2 у вас есть объект, который НЕ является 'B', и вы пытаетесь присвойте ему переменную типа 'B'. Почему все это будет в порядке во время выполнения? –

+0

Потому что мы отдали его B @david – Gpar

ответ

0

В java интерфейс, похожий на класс, является типом. В вашем примере и объект класса A имеет тип A и является типом I. Объект класса B имеет тип B, тип (подтип) A и тип I. Объект класса C относится к типу C, типа (подтипа) B, типа (подтип) A и тип I. Как уже отмечалось, объекты являются типами двух типов (те два типа не имеют никакой связи друг с другом, то есть A и I являются независимо типами) и подтипами их соответствующих суперклассов.

В соответствии с директивой замещения Лескова вы можете использовать подтип (подкласс) вместо супертипа (суперкласса). Для того, чтобы проиллюстрировать взгляд на фрагменте кода ниже:

общественного класса 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, который реализовал I, но полностью не связан с иерархией наследования A. В общем, тогда, когда вам нужно преобразовать между двумя несвязанными типами, вам нужно сделать бросок.

Примечания: Я редактировал код, чтобы включить еще один класс D ПРИМЕЧАНИЯ: Я редактировал код, чтобы включить еще один класс E

+0

Последнее, но 2 строки, вы имеете в виду a = (D) i? @Ironlca – Gpar

+0

@Gpar, я немного изменил код, что я хотел выделить, так это то, что объект типа D, хотя из типа I не является типом A (поскольку A и I являются двумя независимыми типами). Во время компиляции эта строка не будет генерировать ошибки во время выполнения. – Ironluca

+0

Возможно, я немного глуп, чтобы спросить это, извините, почему компилятор can not видит i = d и d не может быть типа A, а затем отображать ошибку времени компиляции, а не исключение времени выполнения? При a = (A) d; является ошибкой времени компиляции @Ironluca – Gpar