Ссылочная переменная суперкласса для объекта подкласса получает доступ к атрибуту подкласса, а не к суперклассу - PullRequest
1 голос
/ 10 марта 2020

В моем коде у меня есть 3 класса: класс A

public class A {
    int x = 1;
    static double y = 3.0;
    public A() {
    x = (int)y;
    }
    public A(int x) {
    this .x = this . getX () + x;
    }
    int getX () {
    return this .x;
    }
    public void f( float z) {
    y *= z;
    }
}

класс B, который расширяется A

public class B extends A {
    int x = 7;
    public B(int x) {
    super (x);
    this .x = x;
    }
    public B() {
    this .y += 1.0;
    }
    int getX () {
    return this .x;
    }
    public void f( long z) {
    y += z;
    }
    public void f( double z) {
    y -= z;
    }
}

и класс M, который включает в себя main функцию

public class M {
    public static void main ( String [] args ) {
        A a1 = new A();
        System .out. println (a1.x + " " + A.y); // OUT: [ ] [ ]
        B b1 = new B();
        System .out. println (b1.x + " " + A.y); // OUT: [ ] [ ]
        System .out. println ((( A)b1 ).x); // OUT: [ ]
        A ab = new B (5);
        System .out. println (ab.x + " " + A.y); // OUT: [ ] [ ]
        System .out. println ((( A)ab ).x); // OUT: [ ]
        A.y = 5.0;
        b1.f (2.0f);
        System .out. println (A.y); // OUT: [ ]
        ab.f (5);
        System .out. println (A.y); // OUT: [ ]
        }
}

Каждая вызываемая функция в методе main ведет себя как ожидалось, за исключением следующих двух:

        A ab = new B (5);
        System .out. println (ab.x + " " + A.y); // OUT: [ ] [ ]
        System .out. println ((( A)ab ).x); // OUT: [ ]

, что дает

5 4.0
5

в качестве вывода, хотя я ожидаю, что он даст

6 4.0
6

Теперь, насколько я понимаю, при создании нового объекта типа B, на который ссылается ссылочная переменная ab типа A, и после вызова правильных конструкторов переменная x в суперклассе должна иметь значение 6, тогда как другой x в подклассе равен 5.

Если это правильно, то ab.x не должно ссылаться на x в суперклассе, что равно 6, поскольку атрибуты и методы c stati (в отличие от -stati c методов) рассматриваются во время компиляции, что означает, что метод println должен печатать переменную в том же классе, что и тип ссылочной переменной?

И в случае (( A)ab ).x) не должно ли x в классе B быть невидимым после чтения ab?

Я был бы благодарен, если бы вы могли провести меня через почему это происходит.

1 Ответ

1 голос
/ 10 марта 2020

Этот оператор this.x = this.getX() + x; in A constructor будет вызывать getX from B, поэтому переменная x в суперклассе будет иметь значение 5, а не 6.

Поэтому, когда вы вызываете этот оператор

A ab = new B (5);

Поток будет

Он вызовет параметризованный конструктор в class B, затем встретится оператор super(x), поэтому он вызовет параметризованный конструктор в class A, где у вас есть этот оператор this.x = this.getX() + x;, который вызовет getX() из class B, который вернет this.x (здесь значение x будет возвращено как 0), поэтому окончательное значение this.x = this.getX() + x; равно (0 + 5 = 5), и this.x будет иметь окончательное значение 5. Таким образом, и class A, и class B значение переменной x будет равно 5.

Поэтому ваши следующие операторы возвращают

System .out. println (ab.x + " " + A.y); // OUT: [5] [3.0]
System .out. println ((( A)ab ).x); // OUT: [5]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...