当我尝试使用Car
接口指向Colorable
类的对象而不使用类car中的implements时,我没有显示任何编译错误(尽管它显示运行时错误)(问题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");
}
}
答案 0 :(得分:8)
Car
的子类实例可能会实现Colorable
,这就是为什么它不是编译时错误。
但是,在问题2中,Vehicle
和Car
是完全独立的 class 层次结构,编译器知道任何Car
引用也不可能对Vehicle
的实例的引用...所以它可以在编译时拒绝它。
基本上,类和接口之间的区别在于接口可以在类型层次结构中进一步实现,而类层次结构只有一个继承链,这意味着编译器可以检测到更多问题。
如果Car
被标记为final
,编译器同样可以告诉Car
的实例也无法实现Colorable
,并且< em> 也是编译时错误。
答案 1 :(得分:2)
在编译期间已知类层次结构。 Java立即知道Car
是否是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!
}
即使Vehicle
未实现Colorable
,Vehicle
的子类也可能。因此运行时没有编译时错误。
答案 2 :(得分:0)
在第一种情况下
Car c=new Car();
Vehicle a = (Vehicle)c;
Colorable i = (Colorable)c;
有两件事 -
然后您使用可着色参考指向汽车对象。现在有可能某些子类汽车实现了Colorable接口。例如
class myCar extends Vehicle implements Colorable{}
然后你做
Car c=new myCar();
Colorable i = (Colorable)c;
这不应该抛出运行时异常。在你的情况下,你告诉编译器相信你会有一些实现Colorable接口的类汽车的子类,但事实并非如此。因此,您将获得编译时错误,但是当您破坏该信任时,您将收到运行时错误。