简体   繁体   English

如何在Java中继承方法

[英]How methods are inherited in java

I am having the following Classes: 我有以下课程:

package com.zee.main;
import com.zee.sub.Sub;

public class MainClass {
    public static void main(String[] args) {
        Sub sub = new Sub();
        sub.add();
    }
}

package com.zee.sup;
public class Super 
{
    private int a = 2;
    private int b = 3;

    public void add(){
        System.out.println("Result: "+(a+b));
        System.out.println("Class:" +this.getClass().getName());        
    }
}

package com.zee.sub;
import com.zee.sup.Super;

public class Sub extends Super {
}

Output: 输出:

Result: 5
Class:com.zee.sub.Sub

How do a Subclass inherit the method of its Superclass ? Subclass如何继承其Superclass Subclass的方法? I was in the assumption that the method defined in the Superclass becomes the part of Subclass but when I checked the compiled bytecode of Sub, I found that there is no add method that was defined in the Super class. 我当时假设Superclass定义的方法成为Subclass的一部分,但是当我检查Sub的编译字节码时,我发现Super类中没有定义add方法。

// Compiled from Sub.java (version 1.6 : 50.0, super bit)
public class com.zee.sub.Sub extends com.zee.sup.Super {

  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public Sub();
    0  aload_0 [this]
    1  invokespecial com.zee.sup.Super() [8]
    4  return
      Line numbers:
        [pc: 0, line: 5]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: com.zee.sub.Sub
}

Following are my questions: 以下是我的问题:

  1. Since there is no add method in the compiled bytecode of Sub, the add method of Superclass must have been called at runtime. 由于Sub的已编译字节码中没有add方法,因此必须在运行时调用Superclassadd方法。

  2. Contradicting the first point is the this.getClass().getName() which returns the runtime class of this Object, but its printing Sub as the runtime class. 与第一点this.getClass().getName()this.getClass().getName() ,它返回此Object的运行时类,但将其打印Sub作为运行时类。

  3. If the runtime class is Sub, then how it is accessing the private fields a and b of the Superclass in its add method? 如果运行时类是Sub,那么它如何通过其add方法访问父类的私有字段ab

Can someone please explain. 有人可以解释一下。 Thanks in advance 提前致谢

Your "questions" aren't exactly questions, but to respond to them: 您的“问题”并非完全是问题,而是要回答它们:

  • If you disassembled the main method, you'd see a call to invokevirtual for add() . 如果反汇编main方法,则会看到对add()调用invokevirtual的调用。 This tells the JVM to look up the appropriate method to call in the class hierarchy, starting with the subclass and working its way up if it doesn't find an implementation there. 这告诉JVM查找在类层次结构中调用的适当方法,从子类开始,如果在子类中找不到实现,则向上进行处理。

  • Object#getClass() is one of the special infrastructure methods in Java. Object#getClass()是Java中的特殊基础结构方法之一。 It's implemented with native code and hooks into the JVM internals to identify the class of the object in question. 它是用native代码实现的,并且钩接到JVM内部以标识所讨论对象的类。

  • The class Sub doesn't access the private members. Sub不会访问私有成员。 The code in Super accesses them. Super的代码可以访问它们。

Since there is no add method in the compiled bytecode of Sub, the add method of Superclass must have been called at runtime. 由于Sub的已编译字节码中没有add方法,因此必须在运行时调用Superclass的add方法。

Yes, method calls are by definition a runtime procedure. 是的,根据定义,方法调用是运行时过程。

Contradicting the first point is the this.getClass().getName() which returns the runtime class of this Object, but its printing Sub as the runtime class. 与第一点相反的是this.getClass()。getName(),它返回此Object的运行时类,但将其打印Sub作为运行时类。

There is no contradiction here. 这里没有矛盾。 The add() method is defined in the superclass, it is not redefined in the subclass, and so when add is called on the subclass, the method from the superclass is invoked. add()方法是在超类中定义的,而不是在子类中重新定义的,因此,在子类上调用add时,将调用超类中的方法。

If the runtime class is Sub, then how it is accessing the private fields a and b of the Superclass in its add method? 如果运行时类是Sub,那么它如何通过其add方法访问父类的私有字段a和b?

It is accessing them by virtue of being a method within the superclass, which has access to that class' private instance variables. 它是作为超类中的一种方法来访问它们的,该方法可以访问该类的私有实例变量。 Normal scope rules apply. 正常范围规则适用。

This may help you overall: as I understand it, when a class is put together, there is what we may think of as a list of methods in a table. 这可能对您有整体帮助:据我了解,当一个类放在一起时,我们可能会认为这是表中方法的列表。 When a method is invoked, really what happens is that the address of the correct method is retrieved from this "jump table". 调用方法时,实际上发生的是从此“跳转表”中检索了正确方法的地址。 In the case at hand, the place in the jump table for add() is occupied by the address from the superclass method. 在当前情况下, add()在跳转表中的位置被超类方法中的地址占据。 That method, in turn, has offsets for accessing things like the private variables; 该方法又具有访问私有变量之类的偏移量。 the setup of the class cleverly puts them at the same offsets in both the subclass and superclass so they'll work in both places. 类的设置巧妙地使它们在子类和超类中处于相同的偏移量,因此它们可以在两个地方使用。

So the add method invoked for the subclass is really the same method, using the same instance variable locations, as it would be for the superclass. 因此,为子类调用的add方法实际上是相同的方法,并且使用相同的实例变量位置,就像对超类一样。

I hope that helps explain things. 我希望这有助于解释问题。

Sub can access private fields from Superclass because Sub is of type Superclass and it gains access to these private fields when calling upon methods defined in Superclass. Sub可以从超类访问私有字段,因为Sub是超类类型,当调用超类中定义的方法时,它可以访问这些私有字段。 It, however, can not call upon these fields when you attempt to make methods that will only belong to the Sub class due to Superclass privatizing "direct" access to these fields from its children. 但是,由于超类私有化了从其子级对这些字段的“直接”访问权限,因此当您尝试创建仅属于Sub类的方法时,它无法调用这些字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM