Если вы перезаписываете поле в подклассе класса, у подкласса есть два поля с одинаковым именем (и разным типом)? - PullRequest
45 голосов
/ 23 февраля 2012

У меня есть 3 класса:

public class Alpha {
    public Number number;
}

public class Beta extends Alpha {
    public String number;
}

public class Gama extends Beta {
    public int number;
}

Почему следующий код компилируется? И почему тест проходит без ошибок во время выполнения?

@Test
public void test() {
    final Beta a = new Gama();
    a.number = "its a string";
    ((Alpha) a).number = 13;
    ((Gama) a).number = 42;

    assertEquals("its a string", a.number);
    assertEquals(13, ((Alpha) a).number);
    assertEquals(42, ((Gama) a).number);
}

Ответы [ 2 ]

62 голосов
/ 23 февраля 2012

Переменные-члены не могут быть переопределены как методы.Переменные number в ваших классах Beta и Gama скрывают (не переопределяя) переменную-член number суперкласса.

С помощью приведения вы можете получить доступ к скрытомучлен в суперклассе.

43 голосов
/ 23 февраля 2012

Поля не могут быть переопределены ;к ним нет полиморфного доступа, во-первых, вы просто объявляете новое поле в каждом случае.

Он компилируется, поскольку в каждом случае тип выражения во время компиляции достаточно для определения какое поле называется number вы имеете в виду.

В программировании в реальном мире вы бы избежали этого двумя способами:

  • Здравый смысл: теневые поля делают ваш кодтруднее читать, поэтому просто не делайте этого
  • Видимость: если вы сделаете все свои поля приватными, подклассы о них все равно не узнают
...