【问题标题】:java inheritance and late bindingjava继承和后期绑定
【发布时间】:2015-03-01 18:17:24
【问题描述】:

我了解以下代码的工作原理,基于多态性和动态绑定。 Java 能够在运行时以某种方式计算出,因为 vh 是一个 MotorBike,我们应该调用 MotorBike 的 move() 方法。

class Vehicle{
    public void move(){
        System.out.println(“Vehicles can move!!”);
    }
}

class MotorBike extends Vehicle{
    public void move(){
        System.out.println(“MotorBike can move and accelerate too!!”);
    }
}

class Test{
    public static void main(String[] args){
        Vehicle vh=new MotorBike();
        vh.move();    // prints MotorBike can move and accelerate too!!
    }
}

我不明白为什么以下代码会中断。我所做的唯一更改是从 Vehicle 类中删除 move() 方法。现在我收到一个编译错误,上面写着“找不到符号 - 方法 move()”。为什么会这样?为什么前面的示例有效而这段代码无效?

class Vehicle{
}

class MotorBike extends Vehicle{
    public void move(){
        System.out.println(“MotorBike can move and accelerate too!!”);
    }
}

class Test{
    public static void main(String[] args){
        Vehicle vh=new MotorBike();
        vh.move();    // compile error
    }
}

【问题讨论】:

  • 因为您已经告诉编译器vh 引用指向Vehicle,并且所有Vecicle 都没有move() 方法。

标签: java inheritance late-binding


【解决方案1】:

Java 有两个密切相关的概念,它们都在这里相关:

  • 每个表达式都有一个类型,它是在编译时确定的。变量vh 的类型为Vehicle,因此表达式vh(仅由该变量组成)的类型为Vehicle
    • 顺便说一句,表达式new MotorBike() 的类型为MotorBike,但由于它是Vehicle 的子类型,编译器可以从前者转换为后者。
  • 每个对象都有一个runtime-type——它是一个实例的类——它是在运行时确定的。 new MotorBike() 创建一个运行时类型为MotorBike 的对象。

当您编写vh.move() 时,如果Vehicle 类没有名为move 的方法,那么编译器不知道您在说什么。

如果Vehicle 确实有一个名为move的方法,那么编译器可以编译它就好了,并把它留给运行时检查相应实例的实际运行时类型,然后派发到正确的方法。 (或者如果 没有 没有相应的实例,因此没有相关的运行时类型,则引发 NullPointerException。)

有些语言,一般称为“动态类型”(或“无类型”或“动态”),没有类型这个概念,只有这个概念运行时类型。此类语言包括 Perl、Python、JavaScript 和许多其他语言。在这样的语言中,vh.move() 的类似物在所有情况下都会被接受,并且运行时会在调用它之前验证该方法是否存在。但是 Java 程序员更喜欢更智能的编译器,它可以帮助我们在 compile-type 上检测到更多的错误。

【讨论】:

    猜你喜欢
    • 2014-07-21
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多