如何在java中继承方法

时间:2014-07-01 15:29:59

标签: java inheritance

我有以下课程:

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 {
}

输出

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

Subclass如何继承Superclass的方法?我假设Superclass中定义的方法成为Subclass的一部分但是当我检查Sub的编译字节码时,我发现没有定义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
}

以下是我的问题:

  1. 由于Sub的已编译字节码中没有add方法,因此必须在运行时调用add Superclass方法。

  2. 矛盾的第一点是this.getClass().getName(),它返回此Object的运行时类,但它的打印Sub作为运行时类。

  3. 如果运行时类是Sub,那么它如何在a方法中访问超类的私有字段badd

  4. 有人可以解释一下。提前致谢

3 个答案:

答案 0 :(得分:3)

你的“问题”不是问题,而是回应它们:

  • 如果您反汇编main方法,则会看到invokevirtualadd()的调用。这告诉JVM查找在类层次结构中调用的适当方法,从子类开始,如果没有在那里找到实现,就会向上运行。

  • Object#getClass()是Java中的一种特殊基础结构方法。 It's implemented with native code并挂钩到JVM内部,以识别相关对象的类。

  • 班级Sub 访问私人会员。 Super中的代码可以访问它们。

答案 1 :(得分:3)

  

由于Sub的编译字节码中没有add方法,因此添加   必须在运行时调用Superclass的方法。

是的,根据定义,方法调用是一个运行时程序。

  

矛盾的第一点是this.getClass()。getName()   返回此Object的运行时类,但其打印Sub为   运行时类。

这里没有矛盾。 add()方法在超类中定义,它没有在子类中重新定义,因此当在子类上调用add时,将调用超类中的方法。

  

如果运行时类是Sub,那么它是如何访问私有的   超类的字段a和b在其add方法中?

它是通过超类中的一个方法来访问它们的,它可以访问该类的私有实例变量。正常范围规则适用。

这可能对你有所帮助:正如我所理解的,当一个类被放在一起时,我们可能会想到一个表中的方法列表。调用方法时,实际发生的是从“跳转表”中检索正确方法的地址。在这种情况下,add()的跳转表中的位置被超类方法的地址占用。反过来,该方法具有访问私有变量等内容的偏移量;该类的设置巧妙地将它们放在子类和超类中的相同偏移处,这样它们就可以在两个地方工作。

因此,为子类调用的add方法实际上是相同的方法,使用相同的实例变量位置,就像对超类一样。

我希望这有助于解释事情。

答案 2 :(得分:-2)

Sub可以从Superclass访问私有字段,因为Sub是Superclass类型,并且在调用Superclass中定义的方法时可以访问这些私有字段。但是,当您尝试创建仅属于Sub类的方法时,它不能调用这些字段,因为Superclass将对其子字段的“直接”访问权限“直接”访问。