Hi Ryan/All,
I am quite interested in this to find out how people are using interfaces, not so much "I don't understand interfaces". I use interfaces to specify what I believe to be a contract between systems, sub-systems and also implementations of strategies etc, however in the majority of cases where I create an interface I tend to create an abstract class that implements the interface and all subsequent implementations are then subclassed of this abstract class, so my argument there is, is there much point at all in defining the interface in the first place. Its hard to ask formulate the question, but I have put in some of my thoughts below.
Interfaces are
used to define contracts between objects where the interface defines common
behaviour
There is nothing in an interface that defines a contract that an abstract class doesn't do. I have found it harder to version my applications with interfaces because I am more likely to break the clients of the interface.
Not only does the IRunnable
interface define a contract that makes semantic sense but we can also use
techniques such as reflection to find all those animals that can run, in which
case we search for those objects that implement the IRunnable interface.
Again, there is nothing there that cannot be achieved with abstract classes.
I sometimes think that the only place interfaces have a benefit over abstract classes is when you want to simulate multiple inheritance. But even that goes against a principle that I have been trying to stick to recently which is keep each class responsible for only one thing.
I hope this has helped you a little. If you are new to .net
and/or development in general you should take a look at the asp.net starter
kits on the asp.net site. You can download these projects and take time to
digest them, the way they are architected and how they use both interfaces and
abstract classes. I would then suggest looking into frameworks such as CSLA and
download their example project. These should all help clarify interfaces. I would suggest that once people have looked at these, read Framework Design Guidelines, because its best advice contradicts most of the "accepted" use of interfaces. Another link is here
http://msdn.microsoft.com/en-us/library/ms229013.aspx and
http://www.theserverside.net/tt/articles/content/FrameworkDesign/Chapter4.pdf (page 80 ish)
Some of the comments of the .Net architects are as follow: (this is based around designing for frameworks, but I think it applies to "normal" application development)
KRZYSZTOF CWALINA I often hear people saying that interfaces specify
contracts. I believe this is a dangerous myth. Interfaces, by themselves,
do not specify much beyond the syntax required to use an object. The interface-
as-contract myth causes people to do the wrong thing when trying to
separate contracts from implementation, which is a great engineering practice.
Interfaces separate syntax from implementation, which is not that useful,
and the myth provides a false sense of doing the right engineering. In
reality, the contract is semantics, and these can actually be nicely expressed
with some implementation.
KRZYSZTOF CWALINA Over the course of the three versions of the
.NET Framework, I have talked about this guideline with quite a few developers
on our team. Many of them, including those who initially disagreed
with the guideline, have said that they regret having shipped some API as
an interface. I have not heard of even one case in which somebody regretted
that they shipped a class.
JEFFREY RICHTER I agree with Krzysztof in general. However, you do
need to think about some other things. There are some special base classes,
such as MarshalByRefObject. If your library type provides an abstract
base class that isn't itself derived from MarshalByRefObject, then types
that derive from your abstract base class cannot live in a different AppDomain.
My recommendation to people is this: Define an interface first and
then define an abstract base class that implements the interface. Use the
interface to communicate to the object and let end-user developers decide
for themselves whether they can just define their own type based on your
abstract base class (for convenience) or define their own type based on
whatever base class they desire and implement the interface (for flexibility).
A good example of this is the IComponent interface and the Component
base class that implements IComponent.
CHRIS ANDERSON Here is one instance in which the design guideline,
if followed too strictly, can paint you into a corner. Abstract types do
version much better, and allow for future extensibility, but they also burn
your one and only one base type. Interfaces are appropriate when you are
really defining a contract between two objects that is invariant over time.
Abstract base types are better for defining a common base for a family of
types. When we did .NET there was somewhat of a backlash against the
complexity and strictness of COM—interfaces, Guids, variants, and IDL,
were all seen as bad things. I believe today that we have a more balanced
view of this. All of these COMisms have their place, and in fact you can see
interfaces coming back as a core concept in Indigo.
BRIAN PEPIN One thing I've started doing is to actually bake as much
contract into my abstract class as possible. For example, I might want to
have four overloads to a method where each overload offers an increasingly
complex set of parameters. The best way to do this is to provide a nonvirtual
implementation of these methods on the abstract class, and have the
implementations all route to a protected abstract method that provides the
actual implementation. By doing this, you can write all the boring argument-
checking logic once. Developers who want to implement your class
will thank you.
Abstract classes and interfaces should not be confused and you
should be clear as to not only what the differences are but why they are used
and when. Whenever concrete implementation is required across multiple objects
you should use abstract classes, but when only behavioural similarities are
required but their implementation is different we should use interfaces.
You don't need any implementation in an abstract class, so maybe don't consider the differences of either abstract or interface, but the limitations of both. I personally don't think the arguments that most people give actually represent the fact. In nearly all cases I can't think of a reason to use interfaces over abstract classes, unless I want to use multiple inheritence.
Paul