Я предполагаю, что вы имели в виду, что последняя строка первого примера кода была b.member.toString()
.
Есть две переменные-члены с именем "member", и в обоих ваших примерах устанавливается только одна из них, поскольку вызывается только одно присваивание this.member
. Чтобы исправить первый пример, вы обычно говорите
public B(SomeClass member) {
super(member);
this.member = member;
}
Но я думаю, что вы уже понимаете это и действительно спрашиваете, почему язык разработан таким образом. Это связано с инкапсуляцией реализации суперкласса. Автор суперкласса должен иметь возможность переписать его, не нарушая подклассы, и наоборот. Представьте себе, если бы B.member
появился первым, потому что автору B было бы неплохо иметь «члена», а позже у автора A возникла та же мысль.
Однако эта система не идеальна, и ваш второй пример показывает, почему. Если сначала пришел B.setMember()
, а затем более поздняя версия A вводит A.setMember()
, то автору A может не предвидеть переопределенный метод B.setMember()
и написать конструктор так, как вы показываете, в результате чего A.member
никогда не инициализируется. C # ввел ключевое слово «overrides», чтобы поймать подобные вещи, а Java заимствовал его как «@overrides», но эта аннотация не является обязательной в Java, поэтому она не так эффективна.