По-перше, уточнення термінології: ми присвоюємо Childоб’єкт змінній типу Parent. Parentє посиланням на об'єкт, який є підтипом Parent, a Child.
Це корисно лише в більш складному прикладі. Уявіть, ви додали getEmployeeDetailsдо класу Батько:
public String getEmployeeDetails() {
return "Name: " + name;
}
Ми могли б замінити цей метод, Childщоб надати більше деталей:
@Override
public String getEmployeeDetails() {
return "Name: " + name + " Salary: " + salary;
}
Тепер ви можете написати один рядок коду , який отримує будь-які деталі , які доступні, чи є об'єкт а , Parentабо Child:
parent.getEmployeeDetails();
Наступний код:
Parent parent = new Parent();
parent.name = 1;
Child child = new Child();
child.name = 2;
child.salary = 2000;
Parent[] employees = new Parent[] { parent, child };
for (Parent employee : employees) {
employee.getEmployeeDetails();
}
Результатом буде результат:
Name: 1
Name: 2 Salary: 2000
Ми використовували a Childяк Parent. Він мав спеціалізовану поведінку, унікальну для Childкласу, але коли ми телефонували, getEmployeeDetails()ми могли ігнорувати різницю та зосереджуватися на тому, як Parentі Childсхожі. Це називається політипом підтипу .
Ваше оновлене запитання задає питання про те, чому Child.salaryнедоступний, коли Childоб’єкт зберігається у Parentпосиланні. Відповідь - перетин "поліморфізму" та "статичного набору тексту". Оскільки Java статично набирається під час компіляції, ви отримуєте певні гарантії від компілятора, але ви змушені дотримуватися правил в обмін, інакше код не компілюється. Тут відповідною гарантією є те, що кожен екземпляр підтипу (наприклад Child) може бути використаний як екземпляр його надтипу (наприклад Parent). Наприклад, вам гарантується, що при доступі employee.getEmployeeDetailsабо employee.nameметод або поле визначено для будь-якого ненульового об’єкта, який може бути призначений змінній employeeтипуParent. Щоб забезпечити цю гарантію, компілятор враховує лише той статичний тип (в основному, тип посилання на змінну Parent), вирішуючи, до чого ви можете отримати доступ. Таким чином , ви не можете отримати доступ до будь-яких членам, які визначені на тип виконання об'єкта, Child.
Коли ви справді хочете використовувати Childяк a, Parentце просто обмеження для життя, і ваш код буде придатним для використання для Parentвсіх його підтипів. Коли це неприйнятно, вкажіть тип посилання Child.