Вот более простой пример одной из проблем с тем, что вы делаете:
class A {
String a;
A(String a) { this.a = a; }
}
class B extends A {
String a;
A(String a) { super(a); }
}
Этот код, вероятно, даст результаты, которые вы не ожидаете:
B b = new B("hello");
System.out.println(b.a); // null
Это может вас удивить, потому что может показаться, что вы инициализировали a
в конструкторе A
с помощью вызова super(a)
.
Но что более удивительно, если вы приведете его к A
, это не печать null
:
System.out.println(((A) b).a); // hello
, что выглядит странно: оно печатает что-то другое, когда вы рассматриваете его как другой тип.
Проблема здесь в том, что поля не являются полиморфными в Java: a
в B
скрывает * a
в A
.Оба поля есть, но когда вы ссылаетесь на a
для переменной типа B
, вы получаете другое поле, когда вы ссылаетесь на a
для переменной типа A
.
Чтобы это работало «менее запутанно», не повторяйте объявление a
в B
:
class A {
String a;
A(String a) { this.a = a; }
}
class B extends A {
A(String a) { super(a); }
}
Сейчас:
B b = new B("hello");
System.out.println(b.a); // hello
System.out.println(((A) b).a); // hello