Куда ссылаются переменные родительских классов проинициализированные объектами дочерних?
Помогите разобраться, я знаю, что здесь должна быть ошибка, но хочу собрать до конца пазл в голове, почему именно она возникает? Есть два класса:
public class Smartphone {
private String type;
@Override
public String toString() {
return "Smartphone{" +
"type='" + type + '\'' +
'}';
}
}
public class ObjectTest {
public static void main(String[] args) {
Object o = new Smartphone();
Smartphone s = o; // ОШИБКА
}
}
Вопросы:
- верно ли утверждение, что ошибка возникает, потому что через переменную родительского класса мы можем получить только объект этого (родительского) класса?
- если да (в чем крайне сомневаюсь), то почему при вызове
o.toString()вызывается переопределенный метод класса Smartphone? - если нет и мы, через переменную родительского класса, получаем объект Smartphone, то почему тогда здесь ошибка
Smartphone s = o;? Знаю, что через переменные родителя можно обращаться только к методам определенным в самом родителе и их переопределенным версиям, но почему нельзя передать значение переменной типа Object в переменную Smartphone, если она ссылается на объект типа Smartphone?
Ответы (1 шт):
Переменная родительского класса может содержать ссылку на объект дочернего класса.
Объявляя переменную определённого типа мы говорим компилятору, что надо проверять, что через эту переменную можно делать с объектом только то, что можно делать с объектом указанного типа.
Если мы точно знаем, что сейчас переменная указывает на экземпляр дочернего класса, мы должны сообщить об этом компилятору, указав настоящий тип объекта:
(Smartphone) o;
Компилятор проверяет выполнение правила, что переменная может ссылаться только на объект того же типа или подтипа этого типа. Как он узнаёт тип объекта: из типа переменной, которая указывает на объект, или из типа возвращаемого значения метода, возвращающего объект, или из кастинга.