I think you have missed the purpose of an interface. If you are using interfaces it may not be best practice to create classes the have public methods which are not part of an interface.
So if your factory produces IAnimal. You should not assume you are getting a Dog class that implements a WagTail method, or a Cat class that LandsOnFeet. You need to define IDog and ICat. (Possibly inheriting from IAnimal).
You then can consider how your factory behaves. You have a couple of options.
A. Generics
You could then create a Generic Factory interface IAnimalFactory which when implemented returns either an IAnimal or the specific type.
public interface IAnimal { int Legs(); } public interface IAnimalFactory<T> where T: IAnimal { IAnimal CreateAnimal(); T CreateSpecificAnimal(); } public interface IDog:IAnimal { void WagTail(); } public interface ICat : IAnimal { void LandOnFeet(); } public class Dog:IDog { //Implementation Excluded } public class Cat : ICat { //Implementation Excluded } public class DogFactory:IAnimalFactory<IDog> { public IAnimal CreateAnimal() { return (IAnimal)CreateSpecificAnimal(); } public IDog CreateSpecificAnimal() { return new Dog(); } } public class CatFactory : IAnimalFactory<ICat> { public IAnimal CreateAnimal() { return (IAnimal)CreateSpecificAnimal(); } public ICat CreateSpecificAnimal() { return new Cat(); } }
The Generic approach gives you some future proofing if you then decide to implement IDomesticDog or IWildDog, and is my preference, but may be more complex then necessary depending on your needs.
B. Specific Methods per SubClass
You could also create a factory that has functions which create a dog or cat of type IAnimal.
public class AnimalFactory { public IAnimal GetDog() { return (IAnimal) new Dog(); } public IAnimal GetCat() { return (IAnimal) new Cat(); } }
Now as advised above you can safely cast to IDog or ICat.
I don't think there is one author that will specifically answer your question. However reading about Inversion of Control and Dependency Injection will likely give you the right level of information you need.