Зачем вообще нужно создавать конструктор, чтобы обратиться к полю?
Помогите понять.
Есть класс родителя, с полем:
public class Pet {
String name;
}
Есть его наследник:
public class Cat extends Pet {
private int age;
}
Почему, при создании объекта наследника я просто не могу указать поле родителя? Каким боком к полю наследника имеет отношение конструктор родителя?
То есть почему я просто не могу сделать так?
Конструктор наследника:
public Cat(String name, int age) {
super(name);
this.age = age;
}
Не создавая конструктор у родителя?
Ведь конструктор же, это по сути просто шаблон с какими полями нужно создать объект.
Ответы (3 шт):
В вашем примере всё довольно однозначно, но стоит его немного усложнить и становится непонятно что делать с данными:
public class Pet {
String name;
String alias;
}
Какой теперь конструктор должен быть? name первый аргумент конструктора, а alias второй?
Хорошо, но что если я ещё захочу дать значение по умолчанию:
public class Pet {
String name;
String alias = "actual pet";
}
Какой конструктор должен быть в этом случае? С двумя аргументами или одним? Или может там должен быть конструктор по умолчанию без аргументов? А что если я в конструкторе ещё хочу произвести трансформацию этой строки, чтобы она удовлетворяла системе (например добавить префикс).
Код должен однозначно описывать желаемое вами поведение, компьютеры, к сожалению, ещё не могут додумать за нас, чего мы хотим.
Ваше утверждение неверно:
Ведь конструктор же, это по сути просто шаблон с какими полями нужно создать объект.
Конструктор вызывается при создании объекта, причем параметры конструктора не определяют с какими полями этот объект создается, а позволяют передать значения переменных в конструктор при его вызове. Эти значения выбираются произвольно, и независимо от полей класса наследника или его родителя. Просто если класс имеет поля, то в конструктор можно передать значения параметров, для того, чтобы инициализировать поля, или для других целей. Названия и количество параметров конструктора необязательно должны соответствовать полям. Если есть параметры, которые имеют названия такие же как названия полей, то для доступа к полям можно использовать ключевое слово this.
Почему, при создании объекта наследника я просто не могу указать поле родителя?
При создании объекта наследника создаются все поля, включая родителя. Они создаются инлайн до вызовов конструкторов. Конструктора вызываются в определенном порядке, о котором можно почитать здесь.
Опять же, если вы думали, что можете указать поле родителя как параметр конструктора, то это неверно. Вам нужно понять, что создание объекта - это сложная процедура, которая производится в определенном порядке, и вызов конструкторов имеет свое место и время.
Каким боком к полю наследника имеет отношение конструктор родителя?
Наверно вы думали, что с помощью конструктора наследника можно инициализировать поля родителя без вызова конструктора родителя. Это неверно. Для инициализации полей родителя можно вызвать конструктор родителя и передать значение поля с помощью super(). Я уже описал выше зачем нужно вызывать конструктор родителя, а к полю наследника действительно никакого отношения не имеет.
Так как у вас поле name у класса Pet не приватное, то без создания родительского конструктора можно сделать так:
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
Если класс Pet у вас лежит в другом пакете, тогда поле name нужно сделать protected:
public class Pet {
protected String name;
}