Иногда вам захочется получить в качестве аргумента родительскую ссылку, и внутри вы, вероятно, захотите сделать что-то специфическое для ребенка.
abstract class Animal{
public abstract void move();
}
class Shark extends Animal{
public void move(){
swim();
}
public void swim(){}
public void bite(){}
}
class Dog extends Animal{
public void move(){
run();
}
public void run(){}
public void bark(){}
}
...
void somethingSpecific(Animal animal){
// Here you don't know and may don't care which animal enters
animal.move(); // You can call parent methods but you can't call bark or bite.
if(animal instanceof Shark){
Shark shark = (Shark)animal;
shark.bite(); // Now you can call bite!
}
//doSomethingSharky(animal); // You cannot call this method.
}
...
В вышеописанном методе вы можете передать либо Акулу, либо Собаку, но что еслиу вас есть что-то вроде этого:
void doSomethingSharky(Shark shark){
//Here you cannot receive an Animal reference
}
Этот метод может быть вызван только путем передачи ссылок на акулу. Поэтому, если у вас есть животное (и это глубоко Акула), вы можете вызвать его так:
Animal animal...
doSomethingSharky((Shark) animal)
В итоге, вы можете использовать родительские ссылки, и, как правило, лучше, если вы не заботитесь о реализации родителя и используете приведение для использования дочернего объекта в качестве конкретного объекта, это будет точно такой же объект,но ваша ссылка знает это, если вы не разыгрываете ее, ваша ссылка будет указывать на тот же объект, но не может быть уверена, какой это будет тип Animal, поэтому позволит вам вызывать только известные методы.