我正在玩一些简单的重载覆盖规则,发现了一些有趣的东西。这是我的代码。
package com.demo;
public class Animal {
private void eat() {
System.out.println("animal eating");
}
public static void main(String args[]) {
Animal a = new Horse();
a.eat();
}
}
class Horse extends Animal {
public void eat() {
System.out.println("Horse eating");
}
}
此程序输出以下内容。
animal eating
这是我所知道的:
- 由于我们有
private void eat()
方法,它不一定会在子类中被访问,所以这里不会出现方法覆盖的问题,因为 JLS明确定义。 - 既然这不是方法覆盖,它肯定不会从 Horse 类调用
public void eat()
方法 - 现在我们的声明
Animal a = new Horse();
因为多态性而有效。
为什么 a.eat()
会调用 Animal
类的方法?我们正在创建一个 Horse
对象,那么为什么要调用 Animal 类的方法呢?
最佳答案
标记为 private
的方法不能在子类中被覆盖,因为它们对子类不可见。从某种意义上说,你的 Horse
类根本不知道 Animal
有一个 eat
方法,因为它被标记为 private
.因此,Java 不会将 Horse
的 eat
方法视为替代方法。这主要是作为一项安全功能而设计的。如果一个类有一个标记为private
的方法,则假设该方法应该只用于类内部,并且外部世界完全无法访问它。如果子类可以覆盖 private
方法,那么它可能会以意想不到的方式改变父类(super class)的行为,这可能是 (1) 意料之外的 (2) 潜在的安全风险。
因为 Java 假定一个类的 private
方法不会被覆盖,所以每当您通过某种类型的引用调用 private
方法时,Java 将始终使用reference 的类型来确定调用哪个方法,而不是使用该引用所指向的 对象的类型 来确定要调用的方法。在这里,引用是 Animal
类型的,所以这就是被调用的方法,即使该引用指向 Horse
。
关于java - 即使对象属于子类,也会调用父类(super class)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39072275/