阴影/变量范围
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()
方法后,解析器在此处执行的操作是:
- 尝试将
getCounter()
解析为 StepCounter
class 的实例
- 失败,尝试找到任何 class 个祖先
- 最近的祖先是
Counter
,所以上下文切换Counter
class
- 尝试在
Counter
class 中解析 getCounter()
- 找到方法,尝试解析
count
的值
getCounter()
是非静态的,所以 count
实际上是 this.count
(如果 getCounter()
是静态的,它将是 Counter.count
)
this.count
在 Counter
class 的实例范围内解析为值 0
0
返回
getCount()
可以 只能访问在父 class 中定义的字段 counter
。此 class 在父 class 的 编译 时间解析。子getCounter()
中没有copy方法
在子class中,可以使用
Counter.this.count
访问父计数器。但是为了避免意外,您永远不应该以这种模棱两可的方式命名字段。
我以为我理解阴影的概念。但是这段代码让我想知道:
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()
方法后,解析器在此处执行的操作是:
- 尝试将
getCounter()
解析为StepCounter
class 的实例
- 失败,尝试找到任何 class 个祖先
- 最近的祖先是
Counter
,所以上下文切换Counter
class - 尝试在
Counter
class 中解析 - 找到方法,尝试解析
count
的值
getCounter()
是非静态的,所以count
实际上是this.count
(如果getCounter()
是静态的,它将是Counter.count
)this.count
在Counter
class 的实例范围内解析为值 0
返回
getCounter()
0
getCount()
可以 只能访问在父 class 中定义的字段 counter
。此 class 在父 class 的 编译 时间解析。子getCounter()
中没有copy方法
在子class中,可以使用
Counter.this.count
访问父计数器。但是为了避免意外,您永远不应该以这种模棱两可的方式命名字段。