#java #inheritance #overriding #parent-child
Вопрос:
Родитель p = новый потомок(); Почему я не могу использовать метод print() в Родителе, не переопределяя его в Потомке?
public class OverridingMethod {
public static void main(String[] args) {
Parent p = new Child();
// why this does not work
p.print();
}
}
class Parent{
/*
public void print(){
System.out.println("Parent Method");
}
*/
}
class Child extends Parent{
public void print(){
System.out.println("Child Method");
}
}
Ответ №1:
Parent p = new Child();
Здесь мы объявляем переменную с именем p
. Его ценность такова new Child()
. Что касается этой конкретной строки кода, мы создаем Child
экземпляр. Однако вы назначили его переменной типа Parent
. Это прекрасно; это называется повышением, и это фундаментальная часть полиморфизма, основанного на наследовании.
Однако, поскольку вы это сделали, компилятор распознает, что p
это тип Parent
. Во всех последующих строках кода Java забыла, что p
на самом деле это a Child
, и только предполагает, что это a Parent
, так как вы сказали ему это предположить. Если Parent
не знает , как print
это сделать, то мы не можем print
этого сделать, потому что мы сказали Java забыть, что у нас есть эта функциональность. Если Parent
знает , как print
это сделать, то мы можем print
это сделать. То, как мы это печатаем, не имеет значения; подклассы могут переопределять это, если только метод не является final
. Все, что имеет значение, — это то, что мы можем.
Теперь Java предоставляет нам бэкдоры в этот механизм. В теории, как только мы напишем
Parent p = new Child();
после этой строки мы никогда не сможем осознать, что p
это Child
снова а. Мы сказали Java относиться к нему как к любому другому Parent
. В общем, это хорошо. Если вы говорите , что что-то является а Parent
, вы должны относиться к этому как к таковому. Если ты хочешь Child
«а», тебе следовало попросить Child
«а». Если нам действительно нужно, мы можем «обмануть» систему типов и посмотреть, что на самом деле в коробке.
if (p instanceof Child) {
Child c = (Child)p;
...
}
Теперь мы «восстановили» первоначального ребенка. Код, который часто использует описанную выше среду выполнения, проверяет, часто ли это признак плохо разработанной кодовой базы.