如何使用界面铸造?

use*_*ser 1 java casting interface

为什么会出现以下输出/错误?

public class A1 {
    public void bar() {
        System.out.println("A1 bar");
    }

    public static void main(String[] args) {
        List<A1> list = new ArrayList<>();
        list.add(new B());
        /* add the missing lines here*/
    }
}

public interface A2 {
      void foo(List<A1> list, int idx);
} 

public class B extends A1 implements A2 {
    public void foo(List<A1> list, int idx) {
        A1 a1 = list.get(idx);
        if (a1 instanceof B) {
            System.out.println("It's a B!");
        } else {
            a1.bar();
        }
    }

    public void bar() {
        System.out.println("B bar");
    }
}
Run Code Online (Sandbox Code Playgroud)

1)将以下行添加到main时:

list.add(new A1());
A2 a=(A2) list.get(0);
a.foo.(list,1);
Run Code Online (Sandbox Code Playgroud)

为什么没有编译错误,因为动态类型不能是接口?(输出是"A1酒吧").

2)为什么以下行导致"运行时错误"而不是"编译错误"?

list.add(new A1());
A2 a = (A2) list.get(1);
a.foo(list, 0);
Run Code Online (Sandbox Code Playgroud)

3)对于以下类层次结论是否正确:

Interface Animal {...}
class Dog implements Animals {...}
class Poodle extends Dog {...}
class Labrador extends Dog {...}
Run Code Online (Sandbox Code Playgroud)

以下行不会编译,因为动态类型是一个接口?

Animal animal=(Animal) poodle;
Run Code Online (Sandbox Code Playgroud)

Flo*_*etz 6

为什么没有编译错误,因为动态类型不能是接口?(输出是"A1酒吧").

某些东西可以同时是A1和A2,例如B.那么为什么编译器只是因为它不在那个(运行时)情况下才显示错误?list.get(0);将返回一个A1,为true,但编译器没有机会知道它是否也是A2.

2)为什么以下行导致"运行时错误"而不是"编译错误"?

两种可能性,取决于您添加它的位置.您要么获得IndexOutOfBoundsException,因为编译器不计算列表的大小.为什么要这样?编译器应该做什么是有限的.在这种情况下,有可能在编译时计算列表大小 - 但在许多其他情况下它不是,因此编译器的工作不是检查这样的东西.

或者你得到一个ClassCastException,因为你得到一个A1对象,并尝试将其转换为A2.这个CAN工作,例如,如果您的A1对象也是B.但在您的情况下,它不是,只是一个简单的,简单的A1对象,它也不是A2.因此你不能把它变成一个.例如,一只狗可能是一只雌性狗,但它没有必要.如果你试图将一个not-FemaleDog投射到FemaleDog中,那么你会得到一个例外.

Animal animal=(Animal) poodle;

...工作得非常好,因为贵宾犬是一只狗,它是一种动物,因此贵宾犬是一种动物.