繁体   English   中英

运行时/编译时多态

[英]runtime/compile time polymorphism

在下面的代码中,为什么b1.subtract()失败。 请解释一下原因,即调用该方法时JVM中会发生什么。

class Base {

public void add() {
System.out.println("Base ADD");
}

}

class Child extends Base {

public void add(){
System.out.println("Child ADD");
}

public void subtract() {
System.out.println("Child Subtract");
}

}

class MainClass {

public static void main(String args[]) {

Base b1 = new Base();
Base b2 = new Child();

Child b3 = new Child();

b1.add();

b2.subtract(); // ?????????**previously it was b1.subtract and its wrong 

b2.add();
b3.subtract();

}

}

我假设,从标题来看,代码实际上是b2.subtract() 跟着那个:

虽然b2目前是Child的一个实例,但很容易看出在你的代码中它总是一个Child的实例,Java是静态类型的,所以不能让你使用实际类的方法,只是声明的类。

考虑这个例子:

Base b2 = Math.random() > 0.5 ? new Base() : new Child();
b2.subtract();

现在在编译时不可能告诉b2实际上是什么实例,所以你显然不可能调用Child中的任何方法(因为b2可能只是一个普通的Base!)。 对于像你的例子这样的例子来说,这是一个例外是没有意义的,因为它会引起很多混乱,这些案例可以很容易地纠正到原样正常工作(通过将声明的类型更改为Child)不是基地)。

JVM中没有任何事情发生,因为代码无法编译。 编译器无法解析方法b1.subtract() ,因为Base没有此类成员。

该类不编译! 假设您要检查实例化子类的基类对象是否有效,答案是肯定的。

    Base b1 = new Base();
    Base b2 = new Child();

    Child b3 = new Child();

    b1.add();

    ((Child) b2).subtract(); // ?????????**

    b2.add();
    b3.subtract();

这将工作,它给出的输出如下。

Base ADD
Child Subtract
Child ADD
Child Subtract

这就是所谓的运行时多态性。

b1变量的类型为Base 该类没有subtract()方法,因此无法编译。

'因为Base没有减法。

b2和b3已减去'因为它们被定义为Child。

[编辑:]不,等等,b2没有减法,即使它是用新的Child()定义的,它仍然被声明为Base。

b1.subtract()的调用可以分解为正在使用的类。

b1 - > Base

subtract() - > Child

由于b1Base ,而不是Child因此对b1.subtract()的调用永远不会起作用,因为b1没有名为subtract()的方法。

编译失败,因为BASE类没有减法方法.B1的类型为base。

subtract()方法不是Base类接口的一部分,这就是它失败的原因。

Java是严格静态类型的语言。 父类不能指向子类方法。 在编译时,Java编译器使用闭包原理并查看Base类中是否有减法方法,因为在这种情况下没有减法方法会导致编译时错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM