Суперкласс с частным статическим полем и подклассом вызывает метод, который изменяет поле. Почему поле не изменяется?
public class B {
private static boolean goo=true;
protected static boolean foo() {
goo=!goo;
return goo;
}
public String bar="Base:"+foo();
public static void main(String[] args) {
B base=new A();
System.out.println("Base:"+goo);//***prints Base:true***
}
}
public class A extends B{
public String bar="Sub:"+foo();
}
Почему программа печатает true
вместо false
Я не понимаю почему goo
не изменилось после foo()
назывался. goo
не скрыт, потому что это личное поле статическое поле перед созданием объекта true
, тогда, когда foo
происходит не должно измениться goo
в куче?
2 ответа
Причина хорошо объяснена в ответе Panz0r, но вы не видите, что у вас есть две переменные вызова bar
, один в A
один в B
,
Если вы добавите метод для печати членов экземпляра в обоих классах (и A
также распечатаю супер класс):
public class Main {
public static void main(String[] args) {
B base = new A();
System.out.println(base);
}
}
class B {
private static boolean goo = true;
protected static boolean foo() {
goo = !goo;
return goo;
}
public String bar = "Base:" + foo();
@Override
public String toString() {
return bar; //print the variable B.bar
}
}
class A extends B {
public String bar = "Sub:" + foo();
@Override
public String toString() {
//print the instance B and the variable A.bar
return super.toString() + "\n" + bar;
}
}
Вы увидите, что оба bar
существовать в случае A
Основание: ложь
Sub: правда
Вы могли бы получить доступ B.bar
переменная с помощью super.bar
если доступность позволила это, но в вашем случае это конфиденциально.
Решение было бы использовать конструктор B
который примет значение и объединит результат foo
,
public String bar;
public B(){
this("Base: ");
}
protected B(String source){ //protected to prevent anybody to use it directly
bar = source + foo();
}
И в A
public A(){
super("Sub: ");
}
Только создание B
позвоню foo
так что вы получите результат:
Sub: false
Давайте проверим это:
System.out.println(new A().bar);
System.out.println(new B().bar);
System.out.println(new A().bar);
Sub: false
База: правда
Sub: false
Потому что вы меняете значение дважды?
true -> public String bar="Base:"+foo(); -> false
false -> public String bar="Sub:"+foo(); -> true