Fog Creek Software
Discussion Board

Welcome! and rules

Joel on Software

Interfaces v. Abstract Classes: question design.

What are some good rules of thumb on using Interfaces vs. Abstract classes? I understand the difference between the two: abstract classes have the *potential* to have both implemented methods as well as "pure virtual" methods.
Each can function as a data type for variables and parameters for methods.

Thanks much,

David Seruyange

David Seruyange
Monday, September 23, 2002

An idiom in the Java API that appeals to me intellectually is "write an interface IFoo, but then implement an abstract class AbstractFoo to ease the burden on implementors".
I rarely factor out an interface from a group of classes in practice though. (Although if your product has a programmatic interface, you have a different problem and should consider the implications of your choices carefully.)

Dominic Cooney
Monday, September 23, 2002

For me, abstract classes are an implementation artifact, while interfaces are a design-level concept. 

It is important to use interfaces in declaration statements, when possible, to allow maximum runtime variation.  Using abstract classes in declarations is a good way to limit or control variation, however.  Similar reasoning applies to what you expose to clients for the purpose of subclassing.

Abstract Interface
Monday, September 23, 2002

Interfaces have a few very powerful uses.

1. An interface makes it possible for a private or protected class implementation to expose a public interface. The memento, visitor and abstract factory patterns can be implemented in this way. I have used interfaces to allow a factory class to create an instance using a private inner class that implement a public interface, making it possible to control instantiation directly.

2. An interface allows you to decouple classes in your design. Often, the adjectives you can apply to your nouns (business objects) can be represented as interfaces: IFormattable, IBillable, IDunnable, or IDisposable.

3. Finally, it is a mechanism to implement multiple inheritance in languages that don't support it directly (Java & C#). Arguably, of questionable significance.

Since an interface cannot inherit or extend any implementation, it is more descriptive than definitive.

Samuel Ford
Monday, September 23, 2002

As a practical matter, you should prefer interfaces to abstract classes when building libraries for other people to use.

The reason is this: .NET is a single inheritance system. Therefore, choosing a base class is a very important decision. Therefore, don't take that decision away from your users; leave them their base class for their own app. Instead, define interfaces that your library can call.

You are of course welcome to ALSO provide a base class that provides do-nothing implementations of the interface methods so that your users don't need to implement it all themselves, but that's only a convienience. Your code should be written to the interfaces.

Argh, it's late and that probably didn't make much sense. :-)

Chris Tavares
Tuesday, September 24, 2002

Whenever I design a set of classes and interfaces I go back to first principles:

* Foo subclasses Bar if and only if a foo IS A bar.
* Foo implements IBaz if and only if a foo CAN DO bar.

Or, equivalently:

* Foo subclasses Bar if and only if bar shares implementation with foo.

Take an example -- "ISerializable" is an interface because it describes what an object CAN DO -- serialize itself.  Any two ISerializable objects need not share any code whatsoever.  So it is an interface, not a base class. 

"TextReader" by contrast is an abstract base class because a StreamReader IS A TextReader and a StreamReader obtains much of its functionality from the base class.

Eric Lippert
Wednesday, September 25, 2002

The practical difference is that once an interface has been published you can never change it without breaking backwards compatability.

Fred Flintstone
Friday, September 27, 2002

Although .NET has made some enhancements in this area -- it isn't as bad as COM...

Michael Giagnocavo
Saturday, September 28, 2002

The key thing to understand regarding "changing interfaces" is that an interface is a _type_.  A type is logically bound to an assembly, and an assembly can have a strong name.

This means that if you correctly version and strong-name your assemblies, there is no "you can't change this interface" problem.  An interface updated in a nerw version of an assembly is a _different_ interface from the old one.

(This is of course yet another good reason to get in the habit of strong-naming assemblies.)

Eric Lippert
Monday, September 30, 2002

*  Recent Topics

*  Fog Creek Home