Interface vs Base class
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.
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:
public abstract class Mammal
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:
public class Dog : Mammal
public class Cat : Mammal
Now let's suppose there are other mammals, which we will usually see in a zoo:
public class Giraffe : Mammal
public class Rhinoceros : Mammal
public class Hippopotamus : Mammal
This will still be valid because at the core of the functionality Feed()
and Mate()
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:
public interface IPettable
{
IList<Trick> Tricks{get; set;}
void Bathe();
void Train(Trick t);
}
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:
public class Dog : Mammal, IPettable
public class Cat : Mammal, IPettable
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.
Well, Josh Bloch said himself in Effective Java 2d:
Prefer interfaces over abstract classes
Some main points:
Existing classes can be easily retrofitted to implement a new interface . All you have to do is add the required methods if they don't yet exist and add an implements clause to the class declaration.
Interfaces are ideal for defining mixins . Loosely speaking, a mixin is a type that a class can implement in addition to its “primary type” to declare that it provides some optional behavior. For example, Comparable is a mixin interface that allows a class to declare that its instances are ordered with respect to other mutually comparable objects.
Interfaces allow the construction of nonhierarchical type frameworks . Type hierarchies are great for organizing some things, but other things don't fall neatly into a rigid hierarchy.
Interfaces enable safe, powerful functionality enhancements via the wrap- per class idiom. If you use abstract classes to define types, you leave the programmer who wants to add functionality with no alternative but to use inheritance.
Moreover, you can combine the virtues of interfaces and abstract classes by providing an abstract skeletal implementation class to go with each nontrivial interface that you export.
On the other hand, interfaces are very hard to evolve. If you add a method to an interface it'll break all of it's implementations.
PS.: Buy the book. It's a lot more detailed.
Modern style is to define IPet and PetBase.
The advantage of the interface is that other code can use it without any ties whatsoever to other executable code. Completely "clean." Also interfaces can be mixed.
But base classes are useful for simple implementations and common utilities. So provide an abstract base class as well to save time and code.
链接地址: http://www.djcxy.com/p/8860.html上一篇: Java核心库中的GoF设计模式示例
下一篇: 接口vs基类