Ich möchte so etwas machen:
List<Animal> animals = new ArrayList<Animal>();
for( Class c: list_of_all_classes_available_to_my_app() )
if (c is Animal)
animals.add( new c() );
Ich möchte mir also alle Klassen im Universum meiner Anwendung ansehen. Wenn ich eine finde, die von Animal abstammt, möchte ich ein neues Objekt dieses Typs erstellen und zur Liste hinzufügen. Auf diese Weise kann ich Funktionen hinzufügen, ohne eine Liste von Dingen aktualisieren zu müssen. Ich kann Folgendes vermeiden:
List<Animal> animals = new ArrayList<Animal>();
animals.add( new Dog() );
animals.add( new Cat() );
animals.add( new Donkey() );
...
Mit dem obigen Ansatz kann ich einfach eine neue Klasse erstellen, die Animal erweitert, und sie wird automatisch aufgenommen.
UPDATE: 16.10.2008 9:00 Uhr pazifische Standardzeit:
Diese Frage hat viele gute Antworten hervorgebracht - danke. Aus den Antworten und meinen Recherchen habe ich herausgefunden, dass das, was ich wirklich tun möchte, unter Java einfach nicht möglich ist. Es gibt Ansätze wie den ServiceLoader-Mechanismus von ddimitrov, die funktionieren können - aber sie sind sehr schwer für das, was ich will, und ich glaube, ich verschiebe das Problem einfach von Java-Code in eine externe Konfigurationsdatei. Update 10.05.19 (11 Jahre später!) Es gibt jetzt mehrere Bibliotheken, die laut @ IvanNiks Antwort helfen können . Org.reflections sieht gut aus. Auch ClassGraph aus der Antwort von @Luke Hutchison sieht interessant aus. Es gibt auch mehrere weitere Möglichkeiten in den Antworten.
Eine andere Möglichkeit, anzugeben, was ich möchte: Eine statische Funktion in meiner Animal-Klasse findet und instanziiert alle Klassen, die von Animal erben - ohne weitere Konfiguration / Codierung. Wenn ich konfigurieren muss, kann ich sie genauso gut in der Animal-Klasse instanziieren. Ich verstehe das, weil ein Java-Programm nur ein loser Verbund von .class-Dateien ist, so ist es eben.
Interessanterweise scheint dies in C # ziemlich trivial zu sein.