Скажем, у вас есть, вы сказали кому-то, что у вас был автомобиль:
class Vehicle {
public void drive() {
System.out.println("Driving vehicle");
}
}
Это означает, что человек, которого вы сказали, знает, что вы способны управлять ... Но тогда у вас есть мотоцикл:
class Motorcycle extends Vehicle {
public void wheely() {
System.out.println("Doing a wheely");
}
public void drive() {
System.out.println("Driving motorcycle");
}
}
Который может drive()
, потому что это Vehicle
, а также делать wheely()
. Но вы никогда не говорили им, что у вас был мотоцикл. Итак, самое большее, что они знают, на что ты способен, это вождение.
Уровень знаний, которыми обладает человек, аналогичен эталонному объекту:
Vehicle vehicle = new Motorcycle();
Справочник Vehicle
только знает, что вы Vehicle
. Неважно, «КАК» вы водите, он просто знает, что вы умеете водить. Итак, когда вы вызываете drive()
, он будет управлять тем, как Motorcycle
управляет (переопределенный метод), но вы все еще ведете.
Но, если вы хотите быть более СПЕЦИАЛЬНЫМ и сказать кому-то тип транспортного средства, которым вы пользовались, был мотоцикл, вы даете им БОЛЬШЕ информации о ВОЗМОЖНОСТЯХ вашего автомобиля.
Motorcycle motorcycle = new Motorcycle();
Вы знаете, поскольку это Vehicle
, он все еще может делать все, что может сделать транспортное средство drive()
. Но, поскольку теперь у вас есть ссылка на подкласс, вы знаете больше о том, что он может делать - wheely()
.
Компилятор не может делать предположения, поэтому, если вы сделаете ссылку Vehicle v
, которая специфична для МЕНЬШЕ (суперкласс), компилятор получит доступ только к элементам этого объекта, к которому он ЗНАЕТ, что он наверняка имеет к ним доступ. Если вы сделаете более конкретную ссылку (подкласс), то вы расскажете компилятору больше о том, что может делать этот объект.