Interface Vs. Abstract Class
Categories:
Language Idioms
Categories: Language Idioms
Interfaces versus Abstract Classes I teach developers things like Design Patterns, Test-Driven Development, Refactoring, and the like. One question that often comes up when implementing a design in a language like Java or C# is “should I use an Interface type or an Abstract Class?” I have an opinion on this, and I get asked this so frequently that I thought a blog entry would be useful. This is related, by the way, to the question “should Interfaces be named using the initial I convention, or not?” I initially said “no, that creates design coupling. Why should clients know or care whether something is an Interface, Abstract Class, Delegate, Event, or any other type?” Now I feel differently about this. To answer both questions, we have to acknowledge that the Interface type, introduced (at least in my experience) in Java and then later supported by .Net, was not created (as many supposed) to compensate for the lack of multiple inheritance. Multiple inheritance was eliminated for different reasons (that I’ll perhaps blog about sometime) and was not thought of as a “loss” to Java. No, the Interface type was introduced to accomplish two different things:
Polymorphism Polymorphism literally means “many forms”, and we generally mean “many forms of a behavior” in software. If you establish an Interface for, say sending data over a connection, then implement this interface in a number of classes each of which does this a different way, then instances of these classes can be up-cast to the Interface type making them appear to be the same. The behavior then will vary depending on which is being used at a given point in time. Of course, you can do this exact same thing using an Abstract Class, which is what leads students to ask the “which one” question in the first place. Participant Flags But an Interface can also be established by a framework service, and any class which implements it can participate in that service. IComparable , for example, means the built-in sorting service of, say, .Net, can be used to sort instances of a given type. Serializable is another example, making it possible to use the built-in mechanism in Java for serializing an object that implements it. This is virtually always done using an Interface, because you might need to make a class capable of participating in more than one of these built-in services. So my answer is this: if your purpose is to create polymorphism, use an Abstract Class. If there are any redundant elements in subclasses, or if any arise in the future, you can easily eliminate said redundancies by moving them into the base (Abstract) Class. You cannot typically do this with an Interface. If, on the other hand you need to mark a class as a candidate for interacting with a provided service (either from an existing framework, or something you provide) then use an Interface type. Whether you use the “I” naming convention is not particularly important to me, but I’d say be consistent. If the services already exist and use this convention, it’s probably best to stick with it when you create your own, and vice-versa.
|