Используйте дженерики вместо удручения. «Даункинг» - это плохо, переходя от более общего типа к более конкретному:
Animal a = hunter.captureOne();
Cat c = (Cat)a; // ACK!!!!!! What if it's a Dog? ClassCastException!
... ты веришь, что a
это кот, но компилятор не может этого гарантировать. Может оказаться собакой во время выполнения.
Вот где вы бы использовали дженерики:
public class <A> Hunter() {
public A captureOne() { ... }
}
Теперь вы можете указать, что хотите охотиться на кошек:
Hunter<Cat> hunterC = new Hunter<Cat>();
Cat c = hunterC.captureOne();
Hunter<Dog> hunterD = new Hunter<Dog>();
Dog d = hunterD.captureOne();
Теперь компилятор может гарантировать, что hunterC будет захватывать только кошек, а hunterD - только собак.
Так что просто используйте обычный полиморфизм, если вы просто хотите обрабатывать определенные классы как их базовый тип. Апкастинг это хорошая вещь. Но если вы попадаете в ситуацию, когда вам нужно обрабатывать определенные классы как их собственный тип, в общем, используйте дженерики.
Или, на самом деле, если вы обнаружите, что вам нужно унизить, используйте дженерики.
РЕДАКТИРОВАТЬ: более общий случай, когда вы хотите отложить решение о том, какие типы обрабатывать. Таким образом, типы становятся параметром, а также значениями.
Скажем, я хочу, чтобы мой класс в зоопарке работал с кошками или губками. У меня нет общего суперкласса. Но я все еще могу использовать:
public class <T> Zoo() { ... }
Zoo<Sponge> spongeZoo = ...
Zoo<Cat> catZoo = ...
степень, в которой вы это запираете, зависит от того, что вы пытаетесь сделать;)
addAnimals(List<Animal>)
и добавить список кошек!