Был на тестировании по Java и столкнулся со следующей задачей.
package com.test;
import java.util.*;
public class Test {
public static void main(String[] args) {
A a = new B();
B b = new B();
System.out.println(a.x);
System.out.println(b.x);
}
}
class A {
int x = 1;
A() {
this.x = 2;
System.out.println("Зашли в конструктор A");
System.out.println(this.x);
}
}
class B extends A {
int x = 3;
B() {
this.x = 4;
System.out.println("Зашли в конструктор B");
System.out.println(this.x);
}
}
В консоли, внезапно, следующее:
Зашли в конструктор A
2
Зашли в конструктор B
4
Зашли в конструктор A
2
Зашли в конструктор B
4
2
4
Переменные, насколько я понимаю относятся к объекту, а не к ссылке. более того, я еще мог бы сам себе это объяснить, если бы не задал бы явно в конструкторе this.x=, мол возможно действительно переменная обносится к ссылке и храниться вообще в стеке а не в куче, но тут явно используется конструктор от класса B....
Соответственно вопрос: почему?
Это явление называется shadowing
.
x
в A
и x
в B
- это разные переменные. Когда Вы обращаетесь к a.x
, это x
из A
, так как тип a
- A
. Что бы получить доступ к B.x
из ссылки a
, надо сделать ((B)a).x
.
Если Вы хотите, чтобы это была одна и та же переменная, закомментируйте int x;
в классе B
.
Для интереса, добавьте в конструктор B
:
System.out.println(((A)this).x);
В отличие от методов переменные не переопределяются в подклассах, они затеняются. Есть такое понятие, как shadowing
.
Когда вы создаете объект типа B
, он содержит в себе как поле B.x
, принадлежащее B
, так и A.x
, принадлежащее A
. Только в A
оно затенилось и его не видно из B
, так как B
имеет переменную с таким же именем. Единственный способ его увидеть, это обратиться к объекту с типом родительского объекта A
, что вы и делаете:
System.out.println(a.x);
Потому что объект а
был создан с типом A
:
A a = new B();
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Я добавляю всплывающую подсказку для счетчика и хочу установить фиксированное местоположение для нееДелаю это так:
пишу приложение для android, при реализации, приведенной ниже, работает прием пакетов, но не работает отправкаесли убрать запуск потока для приема...
Начинаю разбираться в Java и у меня проблемы в преобразовании list в массив