When should I use an interface and when should I use a base class?
Should it always be an interface if I don't want to actually define a base implementation of the methods?
If I have a Dog and Cat class. Why would I want to implement IPet instead of PetBase? I can understand having interfaces for ISheds or IBarks (IMakesNoise?), because those can be placed on a pet by pet basis, but I don't understand which to use for a generic Pet.
Regarding C#, in some senses interfaces and abstract classes can be interchangeable. However, the differences are: i) interfaces cannot implement code; ii) because of this, interfaces cannot call further up the stack to subclass; and iii) only can abstract class may be inherited on a class, whereas multiple interfaces may be implemented on a class.
Don't use a base class unless you know what it means, and that it applies in this case. If it applies, use it, otherwise, use interfaces. But note the answer about small interfaces.
Public Inheritance is overused in OOD and expresses a lot more than most developers realize or are willing to live up to. See the Liskov Substitutablity Principle
In short, if A "is a" B then A requires no more than B and delivers no less than B, for every method it exposes.
An inheritor of a base class should have an "is a" relationship. Interface represents An "implements a" relationship. So only use a base class when your inheritors will maintain the is a relationship.
I usually don't implement either until I need one. I favor interfaces over abstract classes because that gives a little more flexibility. If there's common behavior in some of the inheriting classes I move that up and make an abstract base class. I don't see the need for both, since they essentially server the same purpose, and having both is a bad code smell (imho) that the solution has been over-engineered.
Here is the basic and simple definiton of interface and base class:
cheers
Let's take your example of a Dog and a Cat class, and let's illustrate using C#:
Both a dog and a cat are animals, specifically, quadruped mammals (animals are waaay too general). Let us assume that you have an abstract class Mammal, for both of them:
This base class will probably have default methods such as:
All of which are behavior that have more or less the same implementation between either species. To define this you will have:
Now let's suppose there are other mammals, which we will usually see in a zoo:
This will still be valid because at the core of the functionality
Feed()
andMate()
will still be the same.However, giraffes, rhinoceros, and hippos are not exactly animals that you can make pets out of. That's where an interface will be useful:
The implementation for the above contract will not be the same between a cat and dog; putting their implementations in an abstract class to inherit will be a bad idea.
Your Dog and Cat definitions should now look like:
Theoretically you can override them from a higher base class, but essentially an interface allows you to add on only the things you need into a class without the need for inheritance.
Consequently, because you can usually only inherit from one abstract class (in most statically typed OO languages that is... exceptions include C++) but be able to implement multiple interfaces, it allows you to construct objects in a strictly as required basis.