I want to do something like this:
List<Animal> animals = new ArrayList<Animal>();
for( Class c: list_of_all_classes_available_to_my_app() )
if (c is Anamal)
animals.add( new c() );
So, I want to look at all of the classes in my application's universe and when I find one that descends from Animal, I want to create a new object of that type and add it to the list. This allows me to add functionality without having to update a list of things. I can avoid the following:
List<Animal> animals = new ArrayList<Animal>();
animals.add( new Dog() );
animals.add( new Cat() );
animals.add( new Donkey() );
...
With the above approach, I can simply create a new class that extends Animal and it'll get picked up automatically.
UPDATE: 10/16/2008 9:00am Pacific:
This question has generated a lot of great responses -- thank you. From the responses and my research, I've found that what I really want to do is just not possible under Java. There are approaches, such as ddimitrov's ServiceLoader mechanism that can work -- but they are very heavy for what I want, and I believe I simply move the problem from Java code to an external configuration file.
Another way to state what I want: a static function in my Animal class finds and instantiates all classes that inherit from Animal -- without any further configuration/coding. If I have to configure, I might as well just instantiate them in the Animal class anyway. I understand that because a Java program is just a loose federation of .class files that that's just the way it is.
Interestingly, it seems this is fairly trivial in C#.