为什么在给定方案中允许在编译时将基类类型转换为扩展类?

时间:2014-04-03 19:18:00

标签: java inheritance compilation compiler-errors

我有以下情况。

   public class Fruit { 
   public Fruit() {
    System.out.println("Fruit Constructor");
    }

    public String callSuperApple() {
     return "super fruit";
     }
   }


   public class Apple extends Fruit{
     private String color;

     public String callSuperApple() {
     return "super fruit";
     }    
   }

还有一些第三类:

public class SomeClass{
    private String color;

    public String callSuperApple() {
      return "fruit";
     }
   }

现在主要方法的实施:

public class MainClass{

public static void main(String[] args) {
    Fruit fruit= new Fruit ();
    String string = (String)((Apple)fruit).callSuperApple();//line 3
    System.out.println(string);
}
}

这里我们在运行时有异常,但没有编译时错误。

但是当第3行改为

String string = (String)((SomeClass)fruit).callSuperApple();

抛出编译时错误。方法callSuperApple()也在SomeClassFruit中实施。

现在,Apple是一种Fruit,但我们可以将类型转换fruit转换为Apple。 TypeCasting AppleFruit是有道理的,但不是相反的。为什么在编译时允许这个,而SomeClass只在编译时捕获它?

1 个答案:

答案 0 :(得分:0)

始终允许强制转换。您基本上是在告诉编译器它真的这个类型。 JVM仍将在运行时使用ClassCastException捕获错误。

但是,编译器错误是因为callSuperApple类中没有SomeClass方法。允许使用强制转换,但是消息是在您投放到的类中不存在的方法fruit - SomeClass

<强>加成

现在,随着问题的变化, callSuperApple中的SomeClass方法。现在,编译器错误是error: inconvertible types,因为编译器知道这两个类都不能转换为另一个,因为它们都不是直接或间接的超类。 SomeClass不是Fruit,而Fruit不是SomeClass

你会得到同样的错误:

Number n2 = (Number) "blah";

因为NumberString都不是彼此的超类。