Вопрос, касающийся смешивания переопределения переменных состояния и экземпляра? - PullRequest
1 голос
/ 07 июня 2011

Используя следующий код, (источник) :

    class Parent {
    Integer a = 1;
    static Integer b = 2;
}

class Child extends Parent {
    static Integer a = 41;
    Integer b = 42;
}

public class Test {
    public static void main(String[] args) {
        Parent parent = new Parent();
        Child child = new Child();
        Parent yo = new Child();
        System.out.format("%d %d %d %d %d %d ",
        parent.a,
        parent.b,
        child.a,
        child.b,
        yo.a,
        yo.b);
    }
}

Почему результат yo.a и yo.b 1 и 2 соответственно? Я в замешательстве, поскольку yo указывает на объект Child, в результате он выдает 41 и 2, поскольку в Parent a не является статичным, поэтому вместо него будет напечатана версия a подкласса. версии суперкласса.

Ответы [ 5 ]

2 голосов
/ 07 июня 2011

Переменные (поля) не переопределяются , ни переменные экземпляра, ни переменные класса.

Объект всегда имеет все переменные экземпляра из всех суперклассов.Класс имеет только те статические переменные, которые он сам определяет, хотя он также может обращаться к переменным (и интерфейсам) суперклассов (если они не являются частными).

Если вы переопределите переменную в подклассе, вы будете скрыватьоригинальный, то есть не может напрямую получить к нему доступ.Он все еще существует.

Какая переменная доступна, зависит только от типа (времени компиляции), используемого для доступа к ней, а не от класса конкретного объекта.

1 голос
/ 07 июня 2011

Может быть, этот измененный пример помогает уточнить решение о том, какие поля видны или скрыты, на основе типа времени компиляции:

  public static void main(String[] args) {
    Parent parent = new Parent();
    Child child = new Child();
    Parent yo = new Child();
    System.out.println(parent.a + " " + parent.b);
    System.out.println(child.a + " " + child.b);

    // you said it's a Parent
    System.out.println(yo.a + " " + yo.b);

    // but now you're saying it's a child
    System.out.println(((Child)yo).a + " " + ((Child)yo).b);

    // you said Child, but now you're saying it's a Parent
    System.out.println(((Parent)child).a + " " + ((Parent)child).b);
  }

, который дает вывод:

1 2
41 42
1 2
41 42
1 2

Компилятор принимает решение на основе информации, которую вы ему предоставляете.

1 голос
/ 07 июня 2011

Динамическая привязка для полей отсутствует, все привязки для полей выполняются во время компиляции. Именно поэтому, это печатные поля родительского класса, а не дочернего. Кроме того, статический модификатор не меняет ничего, вы можете удалить все статические модификаторы, а также вы получите тот же результат ..

Следует помнить, что только методы-экземпляры динамически связываются в языке Java.

0 голосов
/ 07 июня 2011

У классов есть поля.Поля экземпляра не могут быть переопределены, только скрыты в подклассах.Локальные переменные не могут быть переопределены или скрыты.Статические поля и метод связаны с классом, и попытка использовать переменную экземпляра вводит в заблуждение, поскольку переменная экземпляра игнорируется.

например,

Parent yo = null;
System.out.println(yo.a); // prints 1

Кстати: лучше использовать int вместо Integer, если вам действительно не нужно целое число.

0 голосов
/ 07 июня 2011

В объектах класса Child нет переменной экземпляра a.Или, точнее, единственная переменная экземпляра a в Child объектах - это та, которая унаследована от Parent;класс Child не определяет собственную переменную экземпляра с именем a.

...