java - 即使对象属于子类,也会调用父类(super class)方法

标签 java oop polymorphism overriding

我正在玩一些简单的重载覆盖规则,发现了一些有趣的东西。这是我的代码。

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 不会将 Horseeat 方法视为替代方法。这主要是作为一项安全功能而设计的。如果一个类有一个标记为private 的方法,则假设该方法应该只用于类内部,并且外部世界完全无法访问它。如果子类可以覆盖 private 方法,那么它可能会以意想不到的方式改变父类(super class)的行为,这可能是 (1) 意料之外的 (2) 潜在的安全风险。

因为 Java 假定一个类的 private 方法不会被覆盖,所以每当您通过某种类型的引用调用 private 方法时,Java 将始终使用reference 的类型来确定调用哪个方法,而不是使用该引用所指向的 对象的类型 来确定要调用的方法。在这里,引用是 Animal 类型的,所以这就是被调用的方法,即使该引用指向 Horse

关于java - 即使对象属于子类,也会调用父类(super class)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39072275/

相关文章:

java - 如何在Scenebuilder/JavaFX中的GridPane中设置所有网格的大小和各种属性

java - 获取PriorityQueue中的第K小元素(Java)

java - Android中如何获取文件的实际路径?

c++组合(有一个)问题

java - Rest API 和 Restful Web 服务之间的区别

c# - 实体和 POCO 的区别

php - $this 不在数据库连接基类的对象上下文中

c++ - 如何为这种 C++ 结构实现复制运算符?

c++ - 如何从存档中检索 true_type?

C++ 多态错误