Abstract Class vs. Interface

G

Guest

My question is more an OOD question. I know *how* to implement both abstract
classes and interfaces. Here's my question - under what circumstacnes does
one use an abstract class and under what circumstacnes does one implement an
interface?

TIA,
 
A

Andy

The answer i've seen is that you should use an abstract class when you
think derived classes will share similar functionality or purpose.

An interface should be used when classes should implement the same
properties / methods, but would otherwise be unrelated.

HTH,
Andy
 
H

Howard Swope

Hey Joe:

I think like many design decisions personal preference comes into play, but
there are certainly some differences.

In C# there is no multiple inheritance. You can only inherit from one base
class, however you can implement multiple interfaces. An abstract base class
can't be directly instantiated, but it can implement code an interface can
only define it. A class that inherits from an abstract base class can choose
to override members or not (unless they are abstract themselves). All
members of an interface must be implemented.

Much of the time a class derived from another class will have a "type of"
relationship with the base class for example:

abstract class Fruit
{
}

class Apple : Fruit
{
}

Often interfaces represent a set of capabilities for example:

interface Eatable
{
public void Chew();
}

class Apple : Fruit, Eatable
{
public void Chew()
{
}
}

Also it depends on how polymorphic your code is. If you have divergent
objects that can be acted on in a similar way with in a system, it makes
sense to define interfaces for example:

class Apple : Fruit, Eatable
{
}

class Cow : Eatable
{
}

It is unlikely that class Cow and class Apple would inherit from the same
base class but it is likely that they would both be acted upon in a similar
way.
 
G

Guest

Andy,

Thanks. This helps. Could you give an example of where classes should
implement the same properties / methods, but would otherwise be unrelated?

I can't think of anything right now.

TIA,
 
S

Samuel R. Neff

An abstract class locks developers into a specific inheritance
hierarchy. This is usually only ok when you're developing both the
base and child classes for an internal project. If the abstract class
is used in other projects or by other developers or if there is any
chance you'll want to inherit from a different base class and provide
the same functionality, then the abstract class can prove to be a huge
problem down the road.

What I usually do is create both an abstract class and an interface.
Have the abstract class implement the interface. Program usage
against the interface, and extensions against the abstract class.
That gives you the ability to provide partial functionality in an
abstract class and also gives you the freedom to use a different
inheritance structure in the future if it's needed.

I have had situations where what we originally thought was acceptable
use of an abstract class later turned out to require an
interface--luckily we had implemented usage via an interface and had
the flexibility to use either.

One common approach is to have an interface for the contract and then
a "helper" class for the partial implementation. All the implementing
classes need to declare all of the required methods, but those that
are common can simply call out to the helper class. The only
disadvantage in this scenario is that the interface can not indicate
that a method must be implemented and must use a specific routine, as
can be accomplished by using a non-virtual method in an otherwise
abstract class.

HTH,

Sam
 
G

Guest

How about ISerializable. Shared by objects that need to be able to be
'converted' to a stream of bytes. Or IEnumerable, shared by objects that are
collections of objects that can be iterated across.

Or, if you want to get outside of the .NET Framework, how about IPrintable,
an interface that could be used to display the current value of an object
onto a device context.

The common thread here is that you're not going to want to force every class
that might want to be serializable, enumerable or printable to derive from
the same base. That's what makes an interface work, in the absense of
multiple inheritance.

Hope that helps.
 
G

Guest

I second the point made by Sam above --

Always declare an interface. Then you can also provide an abstract class or
even a full base class with a complete reference implementation of that
interface.

Now you have no design constraints in the future -- if the abstract (or full
reference) class does part (or all) of what the user needs, they can start
with that and extend/override as needed. If necessary a completely new
implementing class can be created.

Since the calling app uses the Interface contract, any of the above
implementations drops in smoothly.

John
 
M

Mark Broadbent

Andy's point about the abstract class is perfect (I shall give you an
example in a second).
You might consider (in fact you probably already have) what is the
difference (conceptually) between a fully abstract class and an interface?
Well the answer really is not much. Both are complete abstractions -in this
scenario an interface would most probably be more appropriate (although one
difference with abstract here is that you get to play with the
constructor -if you want to overload it etc).

Now onto an example.
Recently I was writing some code for two different inherited TreeNode
controls. Now they each had an identical property and each had identical
code for an overridden ToString() method. One of the controls had an
additional property.

It was important that they could both be accessed through a common type, but
since they both inherited TreeNode, that was already taken care of -this was
one less reason to implement and interface. I could have written an
interface to be implemented by each control *but* that would have not really
given me anything I already didn't have (apart from being able to access the
shared property through this type.
However by creating an abstract type which inherited TreeNode, I could
implement all the shared bits in this (thereby reducing code duplication).
Each control then would only need to inherit this abstract type. By doing
this I also had that benefit that the interface would have given me.

In brief (usually!)
Use an Interface when you want to define a "contract for behaviour"
Use an abstract type when you want to provide the above AND/OR some shared
implementation.

Hope this helps,

Br,

Mark.
 
J

Jonathan Allen

If you expect to add more methods later, you should probably use an abstract
class. Once an interface is in use, it is very hard to change. The abstract
class can at lease offer some default behavior or throw a NotImplemented
exception.
 
J

Jeff Louie

I would favor a pure abstract class (no implementation details) over an
interface if the interface was rapidly evolving, else I would use an
interface. I would use an abstract class with partial implementation
details when I needed to defer the final implementation to a more
knowledgeable class. An example would be a QuickSort routine with an
abstract Compare method.

Regards,
Jeff
 
A

Andy

Joe,

Lets say you're implementing a something that uses a data access class,
but you don't want to lock it a particular data storage system. So
someone could implement a file that reads data from a CSV file, and
another from SQL server. The underlying impelmentation of those
classes would likely be unique to each class, but you want to be able
to talk to them the same way.

At a previous employer, we had some meta data to describe some other
data we were storing (think of a survery system which lets
administrators define their own questions). We had a UI which used the
meta data to gather the actual data and we needed to export this data
to different vendors, each which had their own unique export format.

So we created seperate assemblies to deal with each particular export.
The classes we used to store the data logically should be able to
export it, but given we needed to add new formats an any time we
created the seperate dlls to handle each format.

Each assembly had a class named Exporter that implemented an interface
that lived with the data storage dll.

Our code to do the export looked like this (VB6 code).

oData.Load()
oData.Export( "format1" )

Export looked like this

Sub Export( sFormat as string )
Dim oExporter as IExporter

set oExporter = CreateObject( sFormat & ".Exporter" )

oExporter.Export( Me )
end sub

HTH
Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top