Java 中基 class 中的私有方法动态绑定如何工作?

How does dynamic binding work for private methods in base class in Java?

class Base {
    private void SayHello(){ //PRIVATE
        System.out.println("Hello from Base");
    }
}

class Derived extends Base {
    public void sayHello(){ //PUBLIC
        System.out.println("Hello from Derived");
    }
}

public class TestHello{

    public static void main(String[] args) {
        Derived d = new Derived();
        Base b = d;

        d.sayHello(); //works as expected
        b.sayHello(); //Why does this not work?
    }
}

我想了解:来自基 class 的私有 sayHello 是否对派生 class 可见?还是重新定义?为什么从基指针调用派生的 sayHello 不起作用?我的意思是,如果它是 public(在 Base 中),那么派生的 class 中的 sayHello 就会被调用。所以,我无法理解的是,如果它必须从派生 class 调用 public sayHello,那么为什么要从基 class 中查看访问修饰符?

另外,如果你能给我指出一些简明的资源来帮助我更深入地理解这一点,我将非常感激。谢谢!

b.sayHello() 不起作用,因为当您调用方法 sayHello() 时,计算机开始在基础 class 中寻找该方法,当它找到该方法时,它将看到它是一个私有方法,所以它会告诉你不能使用它。

另一方面,d.sayHello() 可以正常工作,因为计算机将开始在派生的子类中寻找 sayHello(),当计算机找到它时,它会让您使用它,因为它是 public.

is the private sayHello from base class visible to the derived class?

当然没有,因为它有private访问修饰符。

关于访问修饰符的更多信息:

Controlling Access to Members of a Class

or is it a redefinition?

正如您在该问题的已接受答案中所见:

What's the difference between redefining a method and overriding a method?

术语 "redefinition" 不常用。我们可以讨论 "overriding" 和 "overloading",但在您的情况下 Derived class 中的 sayHello 是一种新方法,它不是sayHello 来自 Base class.

And why does the call to the derived sayHello from the base pointer does not work?

只是因为您尝试调用不属于开放 class 接口的方法。

I mean, if it were public (in Base), then the sayHello from the derived class would have been called.

当然,这是预期的多态行为。在这种情况下,Derived class 中的 sayHello 会覆盖 Base class 中的 sayHello,因此您可以调用 sayHello Derived class 通过对 Base class.

的引用

So, what I can not understand is that if it has to call the public sayHello from the derived class, then why look at the access modifier from the base class?

因为你引用了Baseclass而Baseclass的接口中没有sayHello方法。

我在这里找到了很好的讨论:

Overriding private methods in Java

可能对你也有用:

Overriding and Hiding Methods

希望对您有所帮助。

因为下面这行简单地赋值了对象的变量引用Derived

Base b = d;

private 方法是对象私有的,在 class 之外是不可见的。