当前位置: 首页 > 面试题库 >

Java中的继承如何工作?

翟俊名
2023-03-14
问题内容

我们有下课:

class Super {
    void foo() {
        System.out.println("Super");
    }
}

class Sub extends Super {
    void foo() {
        super.foo();
        System.out.println("Sub");
    }
}

public class Clazz {
    public static void main(String[] args) {
        new Sub().foo();
    }
}

输出为:

问题:

什么super礼物?是父级的对象,哪个孩子作为字段保留?

  • 如果是这样,抽象类的继承如何工作?您不能创建抽象类的实例
  • 如果不是,重写方法在哪里保留?

我尝试使用Google,但发现的只是关于如何继承类的常见信息。

更新:

您仍在告诉我明显的事情。也许我的问题没有引起误解,但我将尝试改写一下:

  • 当我们使用调用方法时super,您说的是,我们正在访问父级的方法。但是,如何在没有父对象的情况下调用此方法呢?
  • super一样的this吗?this如您所知,它是对具体对象的引用。

问题答案:

子类不维护任何表示其父类的特殊字段。您可能正在按照内部类的思路进行思考,这些内部类 确实
引用了它们的外部类。这是一种特殊情况,并不代表超子类之间的相互关系。

JVM在内部维护一个“方法表”,将其加载的每个类与该类可用的方法相关联。JVM还知道其加载的所有类之间的关系,包括超级子关系。

当您调用一个super函数时,JVM实际上会做两件事:

  • 确定从中调用该方法的类的父级
  • 确定将在父级上调用的方法
  • 调用方法,并带有特殊说明(invokespecial

如果要检查类的类文件Sub,则该foo方法将显示以下内容:

void foo();
    flags: 
    Code:
        stack=2, locals=1, args_size=1
            0: aload_0       
            1: invokespecial #2        // Method Super.foo:()V
            4: getstatic     #3        // Field java/lang/System.out:Ljava/io/PrintStream;
            7: ldc           #4        // String Sub
            9: invokevirtual #5        // Method java/io/PrintStream.println:(Ljava/lang/String;)V

清单1中的第1行显示了调用超类方法的特殊指令。

Java虚拟机规范(尤其是第2.11.8节)是很好的阅读资料。



 类似资料:
  • 问题内容: 在下面的代码片段中,结果确实令人困惑。 结果是 为什么“ this”在父亲构造函数中指向Son,而“ this.x”却指向父亲在构造函数中的“ x”字段。“ this”关键字如何运作? 我知道 多态的 概念,但是[1]和[2]之间没有区别吗?触发 新的Son() 时,内存中发生了什么? 问题答案: 默认情况下,所有成员函数在Java中都是多态的。这意味着当您调用this.toStrin

  • 问题内容: 当存在内部类时,我很难理解继承在Java中的工作方式。我目前正在处理一些子类需要稍微更改其父类的内部类功能的事情。我在下面提出了一个更简单,类似的示例。 我希望此代码可以打印“我是ChildClass.InnerClass”,但可以打印“我是ParentClass.InnerClass”。为什么是这样?另外,如果我将main中的obj对象更改为ChildClass类型,则输出将更改为“

  • 我一直在做一个基本的类继承练习,尽管我认为我已经掌握了它的jist,但我的程序并没有按应有的方式工作。我遇到了编译错误,但还没有弄清楚原因——如果你们都能在这里帮助我,那就太好了。 首先,这里有三个文件1。人java——基类2。大学生java——一个派生的Person类。java 3。家庭java——不太确定,我认为它是自己的基类 人java有两个实例变量,String name和int age,

  • 问题内容: 假设Java具有以下层次结构类: 这是C#中相同代码的(盲)重复: 当我执行Java代码时,我得到了C#返回的信息。 对我来说,C#的结果更有意义,因为引用B调用了它自己的方法。 Java设计者决定打印而不是打印的逻辑是什么?我的意思是,为什么引用B在C中使用覆盖方法?这种方法的优势是什么? 如何更改Java代码以像C#一样打印出来?我的意思是,我怎么教Java调用它使用的完全引用的方

  • 问题内容: 在插槽上的Python数据模型参考部分中,有关于使用的注释列表。我对第一项和第六项感到完全困惑,因为它们似乎相互矛盾。 第一项: 从没有的类继承时,该类 的属性将始终可访问,因此 子类中的定义是没有意义的。 第六项: 声明的动作仅限于定义它的类。结果,子类将具有一个, 除非它们也定义 (该子类只能包含任何其他插槽的名称)。 在我看来,这些项目可能更好地措辞或通过代码显示,但是我一直在努

  • 我正在尝试继承MutableList,并将我自己的函数添加到它中。例如: 但我得到了以下错误: 类“CompositeJob”不是抽象的,也不实现抽象成员 在Kotlin.Collections.MutableList中定义的公共抽象值大小:Int 我如何继承MutableList,从而可以使用它的原始方法,如add()和isEmpty(),并添加我自己的方法? 多谢了。