java - 令人困惑的方法绑定(bind)

标签 java oop polymorphism dispatch

这个简单程序的输出是这是基础

public class mainApp{
    private void func(){
      System.out.println("This is base"); 
    }

    public static void main(String[] args){
        mainApp newObj = new derived();
        newObj.func();
    }
}

class derived extends mainApp{
    public void func(){ 
      System.out.println("This is derived"); 
    }
}
  • 我的问题是,当我们使用这行 mainApp newObj = new returned(); 时,我们实际上是否没有使用引用创建派生类的对象基类mainApp。那么,当我使用对象调用它的方法时,为什么不从派生类获取该方法呢?为什么我从基类获取方法。

  • 使用这一行,mainApp newObj = new obliged();,我们是在使用 mainApp 的引用,还是在使用 mainApp 的对象em>派生类。哪一个是正确的?

最佳答案

您获得基类方法的原因是 func 的基类版本已声明private ,并且Java不允许私有(private)方法被子类覆盖。这意味着,如果您扩展基类并且纯粹巧合地决定将私有(private)成员函数命名为与基类​​中的私有(private)成员函数相同的名称,则不会意外更改基类成员函数的行为。您确实正在使用 derived 类型的对象,但因为引用静态类型为 mainApp ,调用func被解释为调用私有(private)方法 funcmainApp而不是公共(public)方法funcderived 。更改代码读取

derived d = new derived();
d.func();

修复了这个问题,因为 d 的静态类型现在是derived并调用 func有不同的含义。

在JVM字节码级别,用于调用私有(private)成员函数的指令是invokespecial而用于调用正常的、可重写的成员函数的指令是 invokevirtual 。两者的语义完全不同; invokespecial开始查找当前类(或某些基类,例如构造函数),而 invokevirtual在运行时查找与对象类型相对应的类。

关于java - 令人困惑的方法绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6782826/

相关文章:

java - 如何使用替换/正则表达式替换字符串中的两个字符?

python - 如何在 BaseClass 方法被 Python 中的 DerivedClass 方法覆盖之前执行它

Java,将日志记录委托(delegate)给不同的类是一种不好的做法吗?

java - Java中如何正确使用多态调用正确类的方法

java - 为什么在定长的正则表达式后方这种负向查找不起作用?

java - 将 java.util.Observable 与 MVC java 一起使用

Java:对于每个循环,迭代扩展对象

inheritance - F# 和继承建模

java - 将 ArrayList 值动态传递给其他 ArrayList

c# - 两个对象相互引用可以吗?