阴影/变量范围

Shadowing / Scope of Variables

我以为我理解阴影的概念。但是这段代码让我想知道:

public class Counter {
int count = 0;

public void inc() {
    count++;
}

public int getCount() {
    return count;
}

}

class StepCounter extends Counter {
int count = 0;
int step = 1;

public StepCounter(int step) {
    this.step = step;
}

public void inc() {
    count += step;
}

}

StepCounter sc = new StepCounter(2);
    sc.inc();
    sc.inc();
    System.out.println(sc.getCount());
    System.out.println(sc.count);

所以基本上 sc 的静态类型是 StepCounter。 它的计数器增加了两次,所以在前两个命令之后它是 4。 我的 count 变量不是私有的,它是包私有的(因为我没有声明它的任何可见性)。 因此,如果我在 sc 上调用 .getCount() 方法,它首先会在 StepCounter 中查找它。有none,所以去Counter。它在这里找到了 getCount() 方法。 该方法 return 很重要。如果计数是静态的或私有的,我会理解为什么它 returns 0。但是为什么在这种情况下它 return 0?即使我在 StepCounter 中使变量计数 public,结果仍然是 0。

在 Java 中,无法覆盖字段。只有方法可以被覆盖。因此,在 StepCounter 中使用 'count' 变量不会覆盖超级 class 'Counter' 中的 'count' 字段。它只是创建另一个字段。但是'getCount' 方法returns superclass 中'count' 字段的值。要获得所需的功能,需要覆盖 StepCounter class.

中的 'getCount' 方法

您应该始终尽可能避免阴影,它可能会给您的代码带来严重的不可预测的行为。 您在这里缺少的是 Java 中变量作用域的概念。 count 只是 this.count 的 shorthand。因此,根据您的代码,在调用 getCounter() 方法后,解析器在此处执行的操作是:

  1. 尝试将 getCounter() 解析为 StepCounter class
  2. 的实例
  3. 失败,尝试找到任何 class 个祖先
  4. 最近的祖先是Counter,所以上下文切换Counterclass
  5. 尝试在 Counter class
  6. 中解析 getCounter()
  7. 找到方法,尝试解析count
  8. 的值
  9. getCounter() 是非静态的,所以 count 实际上是 this.count(如果 getCounter() 是静态的,它将是 Counter.count
  10. this.countCounter class
  11. 的实例范围内解析为值 0
  12. 0 返回

getCount() 可以 只能访问在父 class 中定义的字段 counter。此 class 在父 class 的 编译 时间解析。子getCounter()中没有copy方法

在子class中,可以使用

Counter.this.count

访问父计数器。但是为了避免意外,您永远不应该以这种模棱两可的方式命名字段。