В моем коде у меня есть 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
?
Я был бы благодарен, если бы вы могли провести меня через почему это происходит.