【问题标题】:Why type casting of a base class to extended class is allowed at compile time in the given scenario?为什么在给定场景中编译时允许将基类类型转换为扩展类?
【发布时间】:2014-04-03 19:18:00
【问题描述】:

我有以下场景。

   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中实现。

现在,AppleFruit 的一种类型,但我们可以将fruit 类型转换为Apple。将Apple 类型转换为Fruit 是有道理的,但反过来不行。为什么在编译时允许这样做,而 SomeClass 仅在编译时被捕获?

【问题讨论】:

    标签: java inheritance compilation compiler-errors


    【解决方案1】:

    强制转换总是被允许的。 你基本上是在告诉编译器它真的是 this 类型。 JVM 仍然会在运行时捕获带有 ClassCastException 的错误。

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

    加法

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

    你会得到同样的错误:

    Number n2 = (Number) "blah";
    

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

    【讨论】:

    • 该方法已在 SomeClass 和 Fruit 中实现(尽可能),但我仍然有错误。请查看编辑。谢谢
    • 无法从 Fruit 转换为 SomeClass
    • @NihalSharma 我已添加到我的答案中。
    • 那么编译器是否认为这两者都不是?编译器不应该有一个正确/错误的方向吗?只是想知道。
    • 如果转换有可能成功,那么编译器将允许它。如果不可能,那就是编译器错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2021-10-09
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多