2009-12-15 1 views
1

Учась на 6 экзамен SCJP, я натолкнулся на этот вопрос в тест-экзамен:Java унаследовал метод вопрос

class A{ 
    private static String staticProperty = " a "; 
    String getStaticProperty() { return staticProperty; } 
} 

class B extends A { 
    private static String staticProperty = " b "; 
    public static void main(String[] args){ 
     new B().go(new A()); 

    } 
    void go(A t){ 
     String s = t.getStaticProperty() + B.staticProperty + staticProperty + (new B().getStaticProperty()); 
     System.out.println(s); 
    } 
} 

Что выход ??

Выход здесь a b b a

Я прекрасно понимаю a b b, но не понимают «а» в конце. Если вы наследуете метод (в этом случае B наследует getStaticProperty() от A), и этот метод возвращает статическую переменную из родительского (staticProperty), которую вы переопределяете в дочернем элементе, вы ВСЕГДА используете родительскую статическую переменную стоимость??

Кстати, удаление статического идентификатора и создание staticField экземпляра классов возвращает те же результаты. Изменение модификаторов доступа от частного к публичному или другому возвращает те же результаты. Мне нужно было переопределить метод getStaticProperty, чтобы получить то, что я хотел видеть.

ответ

4

Доступ к полю не подлежит dynamic dispatch как доступ к методу, то есть поля не могут быть переопределены. Эта линия в классе А:

String getStaticProperty() { return staticProperty; } 

поэтому относится к области staticProperty в поле класса А. Класс B с тем же именем не имеет значения, а точнее: он шкуры суперкласса поле, и весь код в классе B будет использовать это поле. Sun's Java tutorial это сказать по этому вопросу:

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

3

new B().getStaticProperty() вызывает метод от A, который возвращает статическое свойство A, так как оно находится в диапазоне A.

0

getStaticProperty() - метод, определенный в классе A. Метод не переопределяется классом B, поэтому используется метод из класса A. Поскольку A не может «видеть» статическое свойство B каким-либо образом, он возвращает его собственное значение.

1

Функции являются виртуальными в Java, но члены класса (статические или экземпляры) не являются. Поэтому, в то время как определение B staticProperty может маскировать определение A, оно не отменяет его.

// in B 
String fromChild = staticProperty; // == "b" 
String fromParent = A.staticProperty; // == "a", was masked but not overridden 

Единственный способ получить доступ к переменной, определенной в B является определение функции геттер в А и заменить его в B, как вы предлагаете.

+0

Итак, даже если B наследует метод getStaticProperty() от A (и, следовательно, если бы было так, как если бы B объявлял его сам), этот унаследованный метод все еще ссылается на свойство из суперкласса? Я вижу конфликт с именем участника. Возможно, если staticProperty в B имеет другое имя, все будет легче увидеть. – Dan

1

Когда вы думаете о проблемах с наследованием, таких как этот, вам может быть полезно подумать о том, что произойдет, когда вызывается new B().Когда выполняется конструктор B, первая операция, которую он выполняет (поскольку, поскольку нет явного вызова конструктора A), это super(). На этом этапе создается экземпляр A, и в этом объекте метод getStaticProperty() явно относится к A staticProperty. Затем тело конструктора B запускается (опять же, только после успешного выполнения конструктора A), и поскольку он ничего не делает для изменения или переопределения метода getStaticProperty(), который был создан конструктором A, он, конечно же, не изменяет поведение этого метода.

Это может показаться запутанным изначально, но это может быть полезным способом продумать последствия различных проблем наследования.

+0

Это действительно хорошо написанный ответ на вопрос. Шон прав - призыв к супер является ключевым здесь. –

 Смежные вопросы

  • Нет связанных вопросов^_^