Andy said:
Hi.
I have read tons of blog posts and articles about how and when to use
interfaces. I have seen some people use them to define every object they
create and I have seen some people say to not ever use them. Other people
say not to use them unless you have some actions that multiple objects will
use, an example is like this: You can have an interface that tells all
breeds of cats that they must eat their food, sleep or even meow. Now, you
have different kinds of cats: house cat, farm cat, tiger, lion, panther. All
of these cats do the exact same thing, just in very different ways. This
would be good for the interface because regardless of what kind of cat it
is, the ICat interface will let you define eat(), Meow() and Sleep() without
being stuck to inheriting from a root cat that has this defined. I will go
with this idea, but there has to be more to it than this? An example I deal
with now is this:
I have to create an implement a Headline object that has/does the following
things:
1. It has the properties ModuleID, HeadlineID, Title, BodyText,
CreatedByUser, CreatedDate, ExpirationDate, ActivationDate, Status.
2. It has the events Saving, Saved, Deleting, Deleted, Editing, Edited,
Creating and Created.
3. It has no methods at this point since a headline (news article) really
can't do anything except sit there and look good.
I was told this really wouldn't fit for an interface because it doesn't have
any ability to do anything and that it is just a stateless object. Any ideas
on this matter?
No, the Headline class itself wouldn't fit an interface unless you had
different classes that could *act like* headlines without necessarily
*being* (or actually, inheriting from) one.
As you may know, interfaces are a way to indicate a given behaviour
without providing an inplementation. They are, mainly, an OOP device
for languages that don't have multiple inheritance.
With a language that provides for multiple inheritance, an object may
have more than one ancestor type. For example, a given class may
inherit from both the classes Animal and Food, while other classes
inherit from, say, Animal and Pet, or Food and Vegetable or Animal,
Pet *and* Food (ouch). Each of these base classes contribute to the
derived class "identity". Not only that, those base classes cntribute
with code that the derived class may not need to re-implement.
This is not possible in single inheritance languages (VB.net, C#,
Java...). In such languages a class can only have a single ancestor.
To provide extra functionality, Interfaces were invented: an interface
is like a class without any code in it, just a signature (methods and
properties). A given class may *implement* (that is, provide code for)
any number of interfaces, even though it can only inherit from a
single type.
Moving back to your headline object. Let's assume it's part of a
framework where a Page would contain Headlines, but also Pictures,
Captions, Advertisements, Gadgets, etc. Maybe it would be wise to
provide a base class for all of these items, say, PageElement.
Alternatively, Headlines could also be used in many other contexts: as
part of a NewsArticle, or in a Summary, or as something that could be
listed and edited in a grid, etc, etc. Being just a PageElement
suddenly becomes too restrictive for a HeadLine.
Enter interfaces. For each of these scenarios, you may have generic
behavior that would be required from the participating classes. So,
the elements in a page would be implementations of the IPageElement
interface, with properties such as Page, Position, ZLevel, Hierarchy,
or methods such as Render and Refresh. The elements that could be
edited in a grid would implement the INotifyPropertyChanged interface,
which would raise events whenever a given property had changed. You
could also have your classes implement the ISerializable interface, so
instances could be saved in a arbitrary media.
Implementing those interfaces add "alternate identities" to your base
class, so your Headline class is *also* an IPageElement, an
INotifyPropertyChanged and an ISerializable.
What you don't get by implementing interfaces is a base implementation
-- It's your job to write that code. So, if Headline implements
ISerializable, you must write the code that actually serializes the
object. Compare this with inheritance: when you inherit a class you
usually have some base behavior already implemented.
Just to illustrate, consider when you add a new form to your
application. Your form is a new class which inherits from Form, which
inherits from ContainerControl which inherits from ScrollableControl
which inherits from Control, etc, etc, all way up (or down) to Object:
YourForm >> Form >> ContainerControl >> ScrollableControl >> Control
As you can see, there's a hierarchy, and each hierarchic level
contributes to your form's identity (e.g. an instance of your form is
also a control and a component), but also with implementation (so you
don't need to write the code that manages the form drawing or handles
control intialization, etc, etc). Now, you can decide to change some
of the inherited behavior. To that end, you need only to override the
methods that you intend to change. You don't need, for instance, to
rewrite all the form class from scratch just because you need to
change the way your form handles doubleclicks (fortunately).
Appart from that, your form also implicitly implements a number of
interfaces -- most of which are implemented by those base ancestors:
IComponent, IDisposable, ISynchronizedInvoke, IBindableObject,
IDropTarget, among many others.
These interfaces have no relation with each other or to the classes
that implement then (i.e. no hierarchy whatsoever). In case you decide
to *reimplement* any of then you must completely override the
implementation of a base class, i.e., you must reimplement the
complete interface, not the bits and pieces that you want to add new
behavior. Also, you may implement new interfaces, which will add new
"identities" to your form class, allowing it to be used in other
contexts.
So, as you can (hopefully) see, while inheritance is "atavic" (you and
your brother have the same inheritance, even though you are different
classes), interfaces are "acquired" (you are a doctor, your brother is
a race car lover as well as your neighbor, whom is *also* a doctor).
When to define a new interface? When you need to specify a behavior
that would be provided by classes of different types. When to
implement an interface? When you want your class to participate in
contexts that won't accept its base (or inherited) class.
Hope that helped a little.
Regards,
B.