You already selected the answer to that question, but that could still help.
Although I am a .NET/C# developer, this is really a general OOP problem. I have run in the same kind of problem and I have found a nice solution (I think) using an IoC Container.
If you don't use one yet, that is probably a good reason to start. I don't know IoC containers in Java, but I assume there must be one with similar features.
What I had was a Factory that contains a reference to the IoC container, which is resolved by the container itself (in the BootStrapper)
...
public AnimalFactory(IContainer container)
{
_container = container;
}
You can then setup your IoC container to resolve the correct types based on a key (the sound in your example). It would abstracts completely the concrete classes that your factory needs to return.
in the end, your factory method is shrunk down to this :
...
public Createable CreateAnimal(string action)
{
return _container.Resolve<Createable>(action);
}
This stackoverflow question illustrates the same kind of problem with real world elements and the validated answer shows a draft of my solution (pseudo code).
I later wrote a blog post with the real pieces of code where it is much clearer.
Hope this can help. But it might be overkill in simple cases. I used that because I had 3 levels of dependencies to resolve, and an IoC container already assembling all my components.