Verwenden Sie Generika anstelle von Downcasting. "Downcasting" ist schlecht und geht von einem allgemeineren Typ zu einem spezifischeren über:
Animal a = hunter.captureOne();
Cat c = (Cat)a; // ACK!!!!!! What if it's a Dog? ClassCastException!
... Sie vertrauen darauf, dass a
es sich um eine Katze handelt, aber der Compiler kann dies nicht garantieren. Es könnte sich zur Laufzeit herausstellen, dass es sich um einen Hund handelt.
Hier ist, wo Sie Generika verwenden würden:
public class <A> Hunter() {
public A captureOne() { ... }
}
Jetzt können Sie festlegen, dass Sie einen Katzenjäger wollen:
Hunter<Cat> hunterC = new Hunter<Cat>();
Cat c = hunterC.captureOne();
Hunter<Dog> hunterD = new Hunter<Dog>();
Dog d = hunterD.captureOne();
Jetzt kann der Compiler garantieren, dass hunterC nur Katzen und hunterD nur Hunde erfasst.
Verwenden Sie also einfach den regulären Polymorphismus, wenn Sie nur bestimmte Klassen als Basistyp verwenden möchten. Upcasting ist eine gute Sache. Aber wenn Sie in einer Situation sind, in der Sie bestimmte Klassen als ihren eigenen Typ behandeln müssen, verwenden Sie generische Klassen.
Oder wirklich, wenn Sie feststellen, dass Sie niedergeschlagen werden müssen, verwenden Sie Generika.
BEARBEITEN: Der allgemeinere Fall ist, wenn Sie die Entscheidung darüber aufschieben möchten, welche Arten von Typen behandelt werden sollen. So werden sowohl die Typen als auch die Werte zu Parametern.
Angenommen, ich möchte, dass meine Zoo-Klasse mit Katzen oder Schwämmen umgeht. Ich habe keine gemeinsame Superklasse. Aber ich kann immer noch verwenden:
public class <T> Zoo() { ... }
Zoo<Sponge> spongeZoo = ...
Zoo<Cat> catZoo = ...
Inwieweit Sie dies sperren, hängt davon ab, was Sie tun möchten.
addAnimals(List<Animal>)
eine Liste der Katzen zu schreiben und hinzuzufügen!