Суперкласс с частным статическим полем и подклассом вызывает метод, который изменяет поле. Почему поле не изменяется?

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
Другие вопросы по тегам