Java 如何使用界面铸造?

Java 如何使用界面铸造?,java,interface,casting,Java,Interface,Casting,为什么会出现以下输出/错误 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 mis

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

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");
    }
}
既然动态类型不能是接口,为什么没有编译错误?输出为1巴

2为什么以下几行导致运行时错误,而不是编译错误

list.add(new A1());
A2 a = (A2) list.get(1);
a.foo(list, 0);
3对于以下类层次结构,得出结论是否正确:

Interface Animal {...}
class Dog implements Animals {...}
class Poodle extends Dog {...}
class Labrador extends Dog {...}
因为动态类型是接口,所以无法编译下面的行

Animal animal=(Animal) poodle;
为什么没有编译错误,因为动态类型不能 界面输出为1巴

有些东西可以同时是A1和A2,例如B。那么为什么编译器仅仅因为不在运行时的情况下就显示错误呢?list.get0;将返回A1,true,但编译器没有机会知道它是否也是A2

2为什么以下行会导致运行时错误,但不会导致 编译错误

list.add(new A1());
A2 a = (A2) list.get(1);
a.foo(list, 0);
两种可能性,取决于添加位置。要么您得到了IndexOutOfBoundsException,因为编译器不计算列表的大小。为什么要这样做?编译器应该做的事情是有限制的。在这种情况下,可能可以在编译时计算列表大小,但在许多其他情况下则不可能,因此编译器的工作不是检查这样的内容

或者您得到了一个ClassCastException,因为您得到了一个A1对象,并试图将其转换为A2。例如,如果你的A1对象也是B,这可能会起作用。但在你的例子中,它不是,只是一个简单、普通的A1对象,它也不是A2。所以你不能把它丢进一个。例如,一只狗可能是一只雌性狗,但它不一定非得是。如果你试着把一个非女性化的狗变成女性化的狗,那么你会得到一个例外

动物=动物卷毛狗

…效果非常好,因为卷毛狗是狗,是动物,所以卷毛狗是动物

为什么没有编译错误,因为动态类型不能 界面输出为1巴

有些东西可以同时是A1和A2,例如B。那么为什么编译器仅仅因为不在运行时的情况下就显示错误呢?list.get0;将返回A1,true,但编译器没有机会知道它是否也是A2

2为什么以下行会导致运行时错误,但不会导致 编译错误

list.add(new A1());
A2 a = (A2) list.get(1);
a.foo(list, 0);
两种可能性,取决于添加位置。要么您得到了IndexOutOfBoundsException,因为编译器不计算列表的大小。为什么要这样做?编译器应该做的事情是有限制的。在这种情况下,可能可以在编译时计算列表大小,但在许多其他情况下则不可能,因此编译器的工作不是检查这样的内容

或者您得到了一个ClassCastException,因为您得到了一个A1对象,并试图将其转换为A2。例如,如果你的A1对象也是B,这可能会起作用。但在你的例子中,它不是,只是一个简单、普通的A1对象,它也不是A2。所以你不能把它丢进一个。例如,一只狗可能是一只雌性狗,但它不一定非得是。如果你试着把一个非女性化的狗变成女性化的狗,那么你会得到一个例外

动物=动物卷毛狗


…工作得非常好,因为狮子狗是狗,它是动物,因此狮子狗是动物。

基本上,继承自a2的B:foo方法中缺少@Override注释,请尽量避免使用instanceof。基本上,在继承自a2的B:foo方法中缺少@Override注释,请尽量避免使用instanceof。用它代替它。非常感谢!!你能解释一下为什么在第二个问题中有运行时错误吗?好的,这取决于你把它放在哪里。要么列表的大小只有1,那么get1将抛出一个异常。或者,如果情况并非如此,则获取A1对象并尝试将其转换为A2。但是在这种情况下,A1对象也不是A2,因为它不是B,因此这是一个错误。list.get0是B类型的,所以为什么将其转换为A2是合法的-它可能会切断其扩展的可能性?在示例代码中,您可以有两种类型的对象:A1对象和B对象。每个B对象也是A1对象和附加的A2对象。A1对象就是那个,A1。因此,如果你有一个A1列表,你不能确定其中的每个对象也有A2,因为这只适用于B对象,而不是纯A1对象。非常感谢!!你能解释一下为什么在第二个问题中有运行时错误吗?好的,这取决于你把它放在哪里。要么列表的大小只有1,那么get1将抛出一个异常。或者,如果情况并非如此,则获取A1对象并尝试将其转换为A2。但在这种情况下,A1对象也不是A2,因为它不是B,因此它是一个错误。list.get0是B类型的,所以为什么将其强制转换为A2是合法的-它可能会切断其e
扩展可能性?在示例代码中,可以有两种类型的对象:A1对象和B对象。每个B对象也是A1对象和附加的A2对象。A1对象就是那个,A1。因此,如果你有一个A1列表,你不能确定其中的每个对象也有一个A2,因为这只适用于B对象,而不是纯A1对象。