即使对象是子类也被调用超类方法

普拉萨德·哈卡(Prasad Kharkar)

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

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");
    }
}

该程序输出以下内容。

动物吃

这是我所知道的:

  • 正如我们所拥有的private void eat()方法一样,它不一定要在子类中进行访问,因此,由于JLS对其进行了明确定义,因此在这里不会出现方法覆盖的问题
  • 既然这不是方法重写,那么绝对不会public void eat()从Horse类中调用方法
  • 现在,Animal a = new Horse();由于多态性,我们的声明是有效的。

为什么a.eat()要从Animal类中调用方法我们正在创建一个Horse对象,为什么为什么要调用Animal类的方法?

阿德里安·申(Adrian Shum)

我不确定我是否理解您的困惑。根据您所知道的:

您是对的,Horse.eat()没有被压倒Animal.eat()(因为它是私有的)。换句话说,当您调用时anAnimal.eat(),不会发生后期绑定,因此,您只是在调用Animal.eat(),这就是您所看到的。


从您的其他评论看来,您的困惑似乎是编译器如何决定调用什么。这是一个非常高级的解释:

当编译器看到时Animal a =...; a.eat();,它将尝试解析要调用的内容。

例如,如果看到的eat()是一个静态方法,给出aAnimal对它的引用,则编译器会将其转换为call Animal.eat()

如果它是一个实例方法,并且遇到一个可能被子类覆盖的方法,则编译器将执行的操作是,它不会生成调用特定方法的指令。相反,它将生成指令以从vtable中进行某种查找。从概念上讲,每个对象都有一张小表,键是方法签名,值是对要调用的实际方法的引用。例如,如果在您的情况下Animal.eat()不是私有的,则Horse的vtable将包含类似的内容["eat()" -> "Horse.eat()"]因此,在运行时,给定一个Animal引用并被eat()调用,实际上发生的是:使用,从所引用对象的vtable中进行查找eat(),然后调用关联的方法。(如果裁判指向Horse,相关的方法将是Horse.eat())。在大多数情况下,这就是完成后期绑定魔术的方法。

使用不可能被覆盖的实例方法,编译器会执行与静态方法相似的操作,并生成直接调用该方法的指令。

(以上内容在技术上并不准确,只是一个概念性的插图,供您了解发生的情况)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

当对象是子类类型时,为什么我不能从超类调用子类中的公共方法?

来自分类Dev

从超类对象数组中调用子类方法

来自分类Dev

当子类对象存储在超类数组中时,如何调用子类方法?

来自分类Dev

从子类调用超类的方法

来自分类Dev

NSNotificationCenter从超类还是子类调用方法?

来自分类Dev

Java超类调用子类方法

来自分类Dev

从超类调用子类方法-设计模式

来自分类Dev

NSNotificationCenter从超类或子类调用方法?

来自分类Dev

超类类型对象的子类的构造方法?

来自分类Dev

在C#中,子类对象如何直接调用被重写的超类方法?

来自分类Dev

通过超类实例调用子类类的方法

来自分类Dev

当子类调用超类的方法时,如何获得超类来引用子类中的属性?

来自分类Dev

如何从重写的子类方法调用超类的继承方法?

来自分类Dev

超类引用无法在Java中调用子类方法

来自分类Dev

如何在Java中从超类调用子类方法?

来自分类Dev

AS3:调用超类方法而不是子类实例的替代?

来自分类Dev

在调用方法时获取扩展超类的子类实例

来自分类Dev

java-从动态转换的超类调用子类方法

来自分类Dev

在向量C ++中从超类调用子类方法

来自分类Dev

在子类上调用虚拟方法将返回超类数据

来自分类Dev

Python-如何从子类实例调用超类的方法?

来自分类Dev

在调用方法时获取扩展超类的子类实例

来自分类Dev

您如何在Java中从超类调用子类方法?

来自分类Dev

在子类上调用虚拟方法将返回超类数据

来自分类Dev

从 Java 中超类类型的 ArrayList 调用子类方法

来自分类Dev

如何使超类中的方法创建子类对象?

来自分类Dev

在超类实例的对象上使用子类的方法

来自分类Dev

通过超类对象的ArrayList访问子类方法?

来自分类Dev

超类类型的对象无法访问子类的方法

Related 相关文章

  1. 1

    当对象是子类类型时,为什么我不能从超类调用子类中的公共方法?

  2. 2

    从超类对象数组中调用子类方法

  3. 3

    当子类对象存储在超类数组中时,如何调用子类方法?

  4. 4

    从子类调用超类的方法

  5. 5

    NSNotificationCenter从超类还是子类调用方法?

  6. 6

    Java超类调用子类方法

  7. 7

    从超类调用子类方法-设计模式

  8. 8

    NSNotificationCenter从超类或子类调用方法?

  9. 9

    超类类型对象的子类的构造方法?

  10. 10

    在C#中,子类对象如何直接调用被重写的超类方法?

  11. 11

    通过超类实例调用子类类的方法

  12. 12

    当子类调用超类的方法时,如何获得超类来引用子类中的属性?

  13. 13

    如何从重写的子类方法调用超类的继承方法?

  14. 14

    超类引用无法在Java中调用子类方法

  15. 15

    如何在Java中从超类调用子类方法?

  16. 16

    AS3:调用超类方法而不是子类实例的替代?

  17. 17

    在调用方法时获取扩展超类的子类实例

  18. 18

    java-从动态转换的超类调用子类方法

  19. 19

    在向量C ++中从超类调用子类方法

  20. 20

    在子类上调用虚拟方法将返回超类数据

  21. 21

    Python-如何从子类实例调用超类的方法?

  22. 22

    在调用方法时获取扩展超类的子类实例

  23. 23

    您如何在Java中从超类调用子类方法?

  24. 24

    在子类上调用虚拟方法将返回超类数据

  25. 25

    从 Java 中超类类型的 ArrayList 调用子类方法

  26. 26

    如何使超类中的方法创建子类对象?

  27. 27

    在超类实例的对象上使用子类的方法

  28. 28

    通过超类对象的ArrayList访问子类方法?

  29. 29

    超类类型的对象无法访问子类的方法

热门标签

归档