Java - 覆盖方法时关键字的范围

时间:2017-07-23 05:22:13

标签: java this method-overriding

我对Java中的关键字 this 感到有点困惑,我认为这个指的是当前对象。在下面的例子中,我创建了一个A类和一个扩展A的B类。在主函数中,当我调用 printMyArray 函数时,它打印1 2 3而不是4 5 6 7.是否有我可以调用 printMyArray 函数并打印在B中初始化的数组吗?到目前为止,我可以通过在B类中使用完全相同的方法来实现它,但我觉得这不是最好的方法。

public class Main {

    public static void main(String[] args) {

        B b1 = new B();
        b1.printMyArray();
    }
}

class A {
    private int[] numbers = {1,2,3};

    public void printMyArray() {
        for(int i =0; i < this.numbers.length; i++){
            System.out.println(numbers[i]);
        }
    }
}

class B extends A {
    private int[] numbers = {4,5,6,7};
}

3 个答案:

答案 0 :(得分:2)

班级A中的代码无法访问班级B的私有部分。因此,当您在课程this.numbers的代码中编写A时,它将引用课程numbers中的A字段。当您在课程this.numbers的代码中撰写B时,它会引用课程numbers中的B字段。

请注意,字段不会以与方法相同的方式被覆盖。在您的示例中,类B的对象将携带numbers个字段。你得到哪一个取决于哪个类包含你正在运行的代码。

这就是为超类字段和子类字段使用相同名称通常是一个可怕的想法。

答案 1 :(得分:2)

您在每个班级中定义:

private int[] numbers 

除了private字段外,还没有继承 因此,在numbers类中引用A将始终引用numbers类中声明的A字段。
numbers类中引用B的相同逻辑,它始终引用numbers类中声明的B字段。

所以这里printMyArray()将只使用声明此方法的类的字段:

   public void printMyArray() {
      for (int i = 0; i < this.numbers.length; i++) {
        System.out.println(numbers[i]);
      }
   }

这就是为什么,它的执行总是打印出来:

1,2,3

要解决您的问题,您可以引入公开方法getNumbers(),以便检索每个班级的numbers
由于公共方法可以覆盖,现在可以使用。

A中,添加:

public int[] getNumbers() {
    return numbers;
}

更新printMyArray()方法,以便使用getNumbers()而非numbers字段。

public void printMyArray() {
    for(int number : getNumbers()){
        System.out.println(number);
    }
}

并覆盖getNumbers()中的B方法,以便使用 numbers字段:

private int[] numbers = {4,5,6,7};

public int[] getNumbers() {
    return numbers;
}

您还可以将numbers作为protected字段,以便在B中继承,例如:

protected int[] numbers = {1,2,3};

它保留了getNumbers()方法。

答案 2 :(得分:0)

这是因为A类中存在printMyArray()方法的定义。如果要打印B类对象,则必须在B类中覆盖它。

...
class B extends A {
    public int[] numbers = {4,5,6,7};

    public void printMyArray() {
        for(int i =0; i < this.numbers.length; i++){
            System.out.println(numbers[i]);
        }
    }
}

现在您将输出为:4 5 6 7