Java 接口参考变量

Java 接口参考变量,java,oop,inheritance,interface,Java,Oop,Inheritance,Interface,当我试图用可着色的接口指向Car类的对象,而不在类Car中使用工具时,我没有显示任何编译错误(尽管它显示运行时错误)(问题1)当我尝试对类执行相同的操作时,我没有扩展vehicle类,并尝试用vehicle类指向car的对象,它立即显示编译错误。为什么会这样 问题1: interface Colorable {} class Vehicle {} class Car extends Vehicle {} public class Tester { public static voi

当我试图用
可着色的
接口指向
Car
类的对象,而不在类Car中使用工具时,我没有显示任何编译错误(尽管它显示运行时错误)(问题1)当我尝试对类执行相同的操作时,我没有扩展vehicle类,并尝试用vehicle类指向car的对象,它立即显示编译错误。为什么会这样

问题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");
  }
}
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");
  }
}
问题2:

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");
  }
}
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");
  }
}

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

然而,在问题2中,鉴于
Vehicle
Car
是完全独立的类层次结构,编译器知道任何
Car
引用都不可能同时是
Vehicle
实例的引用。。。所以它可以在编译时拒绝它

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


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

对于
Car
的子类的实例,有可能实现
可着色的
,这就是为什么它不是编译时错误的原因

然而,在问题2中,鉴于
Vehicle
Car
是完全独立的类层次结构,编译器知道任何
Car
引用都不可能同时是
Vehicle
实例的引用。。。所以它可以在编译时拒绝它

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


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

类层次结构在编译时是已知的。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!
}

即使
车辆
没有实现
可着色
车辆
的子类也可能实现。因此,运行时非编译时错误。

类层次结构在编译时已知。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!
}
即使
车辆
没有实现
可着色
车辆
的子类也可能实现。因此,运行时不是编译时错误。

在第一种情况下

Car c=new Car();
Vehicle a = (Vehicle)c;
Colorable i = (Colorable)c;
有两件事-

  • 您正在创建汽车对象。然后,您使用车辆引用指向一个有效的汽车对象,因为您的汽车类扩展了汽车类
  • 然后使用可着色引用指向汽车对象。现在有可能汽车的某些子类实现了彩色接口。比如说

    类myCar扩展车辆实现可着色{}

  • 然后你就这么做了

    Car c=new myCar();
    Colorable i = (Colorable)c;
    
    这不应引发运行时异常。在您的例子中,您告诉编译器相信您,类car的某些子类将实现可着色接口,但事实并非如此。因此,您不会得到编译时错误,但当您打破这种信任时,您将得到运行时错误。

    在第一种情况下

    Car c=new Car();
    Vehicle a = (Vehicle)c;
    Colorable i = (Colorable)c;
    
    有两件事-

  • 您正在创建汽车对象。然后,您使用车辆引用指向一个有效的汽车对象,因为您的汽车类扩展了汽车类
  • 然后使用可着色引用指向汽车对象。现在有可能汽车的某些子类实现了彩色接口。比如说

    类myCar扩展车辆实现可着色{}

  • 然后你就这么做了

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

    这不应引发运行时异常。在您的例子中,您告诉编译器相信您,类car的某些子类将实现可着色接口,但事实并非如此。因此,您不会出现编译时错误,但当您打破这种信任时,将出现运行时错误。

    当您键入问题时,编辑区域旁边有一个方便的“如何格式化”框。这本书值得一读。下面还有一个预览,你可以看到你的问题是什么样子,编辑区上方还有一个格式化工具栏。因为这不是你的第一个问题,请在发帖前花点时间把东西格式化清楚,而不是依赖像Rahul这样的人来帮你。问题2:你不能将c转换为可着色(“可着色i=(可着色)c;”),因为Car没有实现该接口。但如果您能向我们展示您引用的错误输出,这将非常有帮助。可能您至少会收到一条关于未检查强制转换的编译警告……当您键入问题时,编辑区域旁边有一个方便的“如何格式化”框。这本书值得一读。下面还有一个预览,你可以看到你的问题是什么样子,编辑区上方还有一个格式化工具栏。因为这不是你的第一个问题,请在发帖前花点时间把东西格式化清楚,而不是依赖像Rahul这样的人来帮你。问题2:你不能将c转换为可着色(“可着色i=(可着色)c;”),因为Car没有实现该接口。但是如果你能告诉我们错误,那将非常有帮助