1

Car当我尝试用接口指向类的对象Colorable而不使用类 car 中的实现时,我没有显示任何编译错误(尽管它显示运行时错误)(问题 1)并且当我尝试对我不扩展的类执行相同操作时车辆类并尝试用车辆类指向汽车对象它立即显示编译错误。为什么会这样?

问题1:

interface Colorable {}

class Vehicle {}

class Car  extends Vehicle {}

public class Tester {

  public static void main(String[] args) {

    Car c=new Car();
    Vehicle a = (Vehicle)c;

    Colorable i = (Colorable)c;

    System.out.println("Successful");
  }
}

问题2:

interface Colorable {}

class Vehicle {}

class Car   {}

public class Tester {

  public static void main(String[] args) {

    Car c=new Car();
    Vehicle a = (Vehicle)c;

    Colorable i = (Colorable)c;

    System.out.println("Successful");
  }
}
4

3 回答 3

8

子类的实例可能Car实现Colorable,这就是为什么它不是编译时错误。

但是,在问题 2 中考虑到Vehicle并且Car是完全独立的Car层次结构,编译器知道任何引用不可能同时也是对Vehicle... 的实例的引用,因此它可以在编译时拒绝它。

基本上,类和接口之间的区别在于,接口可以在类型层次结构中进一步实现,而层次结构只有一个继承链,这意味着编译器可以检测到更多问题。

如果Car被标记为final,编译器同样能够判断 的实例不可能Car同时实现Colorable也是一个编译时错误。

于 2013-08-19T12:34:46.453 回答
2

类层次结构在编译时是已知的。Java 立即知道是否Caris-a Vehicle

接口更棘手。考虑这段代码:

interface Colorable {}

class Vehicle {}

class Car extends Vehicle implements Colorable {}

{
  // case 1:
  Vehicle vehicle1 = new Vehicle();
  Colorable colorable = vehicle1; // error

  // case 2:
  Vehicle vehicle2 = new Car();
  Colorable colorable2 = vehicle2; // OK! Car implements Colorable!
}

即使 aVehicle没有实现Colorable,may 的子类Vehicle。因此运行时不是编译时错误。

于 2013-08-19T12:36:05.693 回答
0

第一种情况

Car c=new Car();
Vehicle a = (Vehicle)c;
Colorable i = (Colorable)c;

有两件事——

  1. 您正在创建一个 Car 对象。然后,您使用 Vehicle 引用指向一个有效的汽车对象,因为您的 Car 类扩展了 Vehicle 类。
  2. 然后您使用 Colorable 引用指向汽车对象。现在有可能汽车的某些子类实现了 Colorable 接口。例如

    class myCar extends Vehicle implements Colorable{}

然后你做

Car c=new myCar();
Colorable i = (Colorable)c;

这不应该引发运行时异常。在您的情况下,您告诉编译器相信您会有一些 car 类的子类可以实现 Colorable 接口,但事实并非如此。所以你会得到一个编译时错误,但是当你打破这种信任时,你会得到一个运行时错误。

于 2013-08-19T12:49:52.730 回答