Скрытые поля через наследование - PullRequest
10 голосов
/ 27 декабря 2011

В следующем примере кода:

class Parent { 
    int x =5;
    public Integer aMethod(){

        System.out.print("Parent.aMthod ");
        return x;
    }
}

class Child extends Parent {
    int x =6;
    public Integer aMethod(){
        System.out.print("Child.aMthod "); 
        return x;
    }
}


class ZiggyTest2{

    public static void main(String[] args){

        Parent p = new Child();
        Child c = new Child();

        System.out.println(p.x + " " + c.x);

        System.out.println(p.aMethod() + "  \n");
        System.out.println(c.aMethod() + "  \n");
    }   
}

И вывод:

5 6
Child.aMthod 6  

Child.aMthod 6

Почему p.aMethod() не печатает 6, когда px печатает 6?

Спасибо

Редактировать

Упс, небольшая опечатка: вопрос должен быть «почему p.aMethod () не печатает 5, когда px печатает 5» - Спасибо @ thinkteep

Ответы [ 3 ]

12 голосов
/ 27 декабря 2011

При доступе к полям члена класса (переменным экземпляра), таким как p.x, полиморфное разрешение не выполняется.Другими словами, вы получите результаты из класса, который известен во время компиляции, а не из того, что известен во время выполнения.Они отправляются во время выполнения объекту фактического класса, на который указывает ссылка, даже если сама ссылка имеет супертип.(в виртуальной машине это происходит через код операции invokevirtual, см., например, http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc6.html#invokevirtual).

1 голос
/ 27 декабря 2011

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

0 голосов
/ 27 декабря 2011

Потому что объявление переменной не наследуется.У вас есть две копии x в классе, одна в родительском пространстве имен, другая в дочернем пространстве имен.

...