Interfaces vs Classes

F

Frank Rizzo

We are having one of those religious debates at work: Interfaces vs
Classes. My take is that Classes give you more flexibility. You can
enforce a contract on the descendant classes by marking methods abstract
(which is all that an interface does). In addition, the classes allow
you to be flexible by adding functionality that child classes inherit.
Or by providing optional functionality via virtual methods.

Now, I understand that Interfaces have its place, but I am having a hard
time finding a situation where the classes (via inheritance) do not
provide an identical or better solution.

Am I missing something? I am open to arguments from both sides.

Regards.
 
T

Telmo Sampaio

Hi Frank,

It is normal to feel like that. The big advantage of using interfaces is
that they extend the use of polymorphism beyond the class hierarchy. They
are normally used to create small frameworks as well. Here are two examples:

- imagine you are responsible for writing an ATM application for a bank.
Thru your application you will allow users to Deposit, Withdraw and check
their Balance for Checking accounts and Savings Accounts. No matter what
kind of account your application handles, it needs to execute those tree
operations. You can sure derive Checking and Savings from an abstract
BankAccount that contain the necessary members. Now imagine that in the
future, your ATM application may also be used to access Credit Card accounts
and that the CreditCard class is not in the same inheritance hierarchy as
the BankAccounts. You still need to force it to have the Deposit, Withdraw
and Balance members. An interface is the perfect solution here.

- another real example. You are probably aware of the Sort method for the
Array class. It sorts data in a single dimension array. Remember that arrays
can be of any type: integers, strings, Animals, BankAccounts, etc. The Sort
method does not care about the data type. It access the underlying object
thru the IComparable interface. Therefore, to make your classes sortable,
you need to implement the IComparable interface. This has nothing to do with
inheritance.

I hope this helps a little bit.

Telmo Sampaio
MCT
 
S

sushant.bhatia

Lets say you wanted to make a Plugin architecture to your application
where 3rd party developers could develop components for your app to use
at runtime. Would you be willing to give them the class or would you
rather just tell them about the interface? :)
QED.
 
C

Colin Stutley

Remoting.
You do not want to distribute server based classes, just the interface to
that class.

- Colin.
 
J

Jeff Louie

Frank...In C++ you have a good argument, but not in C# simply due to the
fact that C# does not support multiple inheritance of implementation eg.
C++ style multiple inheritance. So you are limited to extending from a
single class. Interfaces are much more flexible in that you can
implement more than one interface.

In summary, if you have a well defined contract that will be implemented
by many classes use an interface. If the contract is evolving, consider
using a base class as you suggest. Use a base class if you need to
include implementation details.

Regards,
Jeff
Now, I understand that Interfaces have its place, but I am having a hard
time finding a situation where the classes (via inheritance) do not
provide an identical or better solution.
 
H

Helge Jensen

Frank said:
We are having one of those religious debates at work: Interfaces vs
Classes.
My take is that Classes give you more flexibility.

Well, there are two dimensions of flexibility here: for the definer and
the user of the interface/class.

All the languages i know that distiguish between interfaces and classes
(C#, JAVA, ...not C++) have this distinction because they don't want to
have the multiple-inheritance problem with offset-based member-fields.
In short you can mutiple implement interfaces and singularly inherit
classes.

The multiple-inheritance problem does not prevent interfaces from
actually defining code, which unfortunately none of C# or JAVA allows.

So a class allows you to specify static- and member-fields (and method
content), giving the definer flexibility.

Using an interface allow implementation to still inherit and to
implement other interfaces, giving the implementer flexibility.

Obviosly, for actual implementation a class is needed.

Other than that, my opinion is that neither classes nor interfaces
should be "generally preferred" when passing data around, since they are
both valuable assets in programming with respective strengths and
weaknesses. You need to choose based on the situation, not a "general rule".
You can
enforce a contract on the descendant classes by marking methods abstract
(which is all that an interface does).

So, If that's what you need, use an interface (if it's not too much
code), otherwise use a class.

Remember that you can reuse code by other means than inheritance,
compostion works fine (especially in garbage-collected languages). You
can also define helper-functions which implementers can use.
In addition, the classes allow
you to be flexible by adding functionality that child classes inherit.

This is valuable if all implementations shares a way of coding... or if
there is only 1 :)

But, you could easily put that code in a helper-class and allow other
the choice of whether to use the helper-class.

interface Foo { void f(int i); }
class DefaultFoo implements Foo { void f(int i) { /* impl. */ } }

But remember, less lines of code also means less bugs, so use the
construct judiciously :)
Or by providing optional functionality via virtual methods.

Optional? you specificly mean optionally overridden, right?

The same construct as above applies.
Now, I understand that Interfaces have its place, but I am having a hard
time finding a situation where the classes (via inheritance) do not
provide an identical or better solution.

If you are in C# (or JAVA): Multiple implementation, it's the one and
only thing that interfaces can do that classes cannot.

You can argue all day about whether it's a good or bad idea, but it is
often needed to bridge two colliding conceptions of the same thing...
*very* often frameworks give you this problem.

If you do cross-language integration using .NET, for example using COM,
you should know that some tools only map interfaces between languages.
Am I missing something? I am open to arguments from both sides.

Well, multiple implementation is a valuable thing to be able to do.
Besides, there are many ways to workaround the problem that interfaces
cannot specify method-code.

I think you really just have to accept that neither interfaces nor
classes are superfluous and you need to be able to decide in a
case-by-case manner which one to use in order to minimize work and
maximize usability.
 
J

Jeffrey Palermo, MCAD.Net

Frank,
I can't but wonder if you are the Frank Rizzo from all the Jerky Boys
albums. :)

Anyway, I rule of thumb I like is to favor an Interface first. Then
that can define that portion of your API. Then if you have some common
functionality that you would like to be implemented in a base class,
the argument to use an abstract class is stronger. Under no condition
should you use an abstract class with only abstract members. That adds
no value beyond the interface implementation but puts an unneeded
restriction on its use.

Image if we didn't have an IDisposable interface but an abstract class
instead. To implement the pattern, we'd have to derive from that
class. Classes that already have a base would be stuck like chuck and
would not be able to implement the pattern.

Sometimes these arguments don't hit home until you've made an
implementation using inheritence and been personally hit with one of
these roadblocks. There's no replacement for experiences!

Best regards,
Jeffrey Palermo
 
N

Nick Malik [Microsoft]

Just to add to the excellent discussions here...

I, too, favor interfaces first, and then base classes. This is because of a
common issue with OO designs where it is tempting to create "tall trees" in
the heirarchy, each decendent specializing just one little bit of the
ancestor, until you end up with a tree that is five, six, even seven levels
deep. This becomes intensely difficult to debug, and a single defect in a
base class can make the entire structure frail.

Using Interfaces gives you the advantage of an enforced contract (you know),
multiple inheritance (as was pointed out by other posters) and also
discourages these tall trees.

Sometimes we need them. Don't get me wrong. There is no "one right answer"
to anything in OOP. But I find that it's a good idea to consider,
carefully, what it is I want to "abstract" in my class. The effort that I
expend trying to solve the problem with interfaces, first, helps me to do
that.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
 
T

Telmo Sampaio

I wrote this last night... I dunno why it did not go thru...

Hi Frank,

It is normal to feel like that. The big advantage of using interfaces is
that they extend the use of polymorphism beyond the class hierarchy. They
are normally used to create small frameworks as well. Here are two examples:

- imagine you are responsible for writing an ATM application for a bank.
Thru your application you will allow users to Deposit, Withdraw and check
their Balance for Checking accounts and Savings Accounts. No matter what
kind of account your application handles, it needs to execute those tree
operations. You can sure derive Checking and Savings from an abstract
BankAccount that contain the necessary members. Now imagine that in the
future, your ATM application may also be used to access Credit Card accounts
and that the CreditCard class is not in the same inheritance hierarchy as
the BankAccounts. You still need to force it to have the Deposit, Withdraw
and Balance members. An interface is the perfect solution here.

- another real example. You are probably aware of the Sort method for the
Array class. It sorts data in a single dimension array. Remember that arrays
can be of any type: integers, strings, Animals, BankAccounts, etc. The Sort
method does not care about the data type. It access the underlying object
thru the IComparable interface. Therefore, to make your classes sortable,
you need to implement the IComparable interface. This has nothing to do with
inheritance.

I hope this helps a little bit.

Telmo Sampaio
MCT
 
F

Frank Rizzo

Jeffrey said:
Frank,
I can't but wonder if you are the Frank Rizzo from all the Jerky Boys
albums. :)

Hey, there, sweet tits. No, I am not.
Anyway, I rule of thumb I like is to favor an Interface first. Then
that can define that portion of your API. Then if you have some common
functionality that you would like to be implemented in a base class,
the argument to use an abstract class is stronger. Under no condition
should you use an abstract class with only abstract members. That adds
no value beyond the interface implementation but puts an unneeded
restriction on its use.

Image if we didn't have an IDisposable interface but an abstract class
instead. To implement the pattern, we'd have to derive from that
class. Classes that already have a base would be stuck like chuck and
would not be able to implement the pattern.

Sometimes these arguments don't hit home until you've made an
implementation using inheritence and been personally hit with one of
these roadblocks. There's no replacement for experiences!

I get that. But, my rule has been what I learned in Intro to OOP 10
years ago. Interface is a "can-be", while Class is a "is-a". In my
case, one developer want to define an interface called, IDoThis and then
derive the class called CDoThis that implements IDoThis. To me, it
makes no sense whatsoever.

IDisposable makes sense because the class that implements it "can-be"
IDisposable. It is not "is-a" IDisposable. In fact, if you look at the
.NET framework, you won't find a single case of straight down
(IDoSomething, that's implemented by CDoSomething) encapsulation.
 
F

Frank Rizzo

Nick said:
Just to add to the excellent discussions here...

I, too, favor interfaces first, and then base classes. This is because of a
common issue with OO designs where it is tempting to create "tall trees" in
the heirarchy, each decendent specializing just one little bit of the
ancestor, until you end up with a tree that is five, six, even seven levels
deep. This becomes intensely difficult to debug, and a single defect in a
base class can make the entire structure frail.

Using Interfaces gives you the advantage of an enforced contract (you know),
multiple inheritance (as was pointed out by other posters) and also
discourages these tall trees.

Sometimes we need them. Don't get me wrong. There is no "one right answer"
to anything in OOP. But I find that it's a good idea to consider,
carefully, what it is I want to "abstract" in my class. The effort that I
expend trying to solve the problem with interfaces, first, helps me to do
that.

Thank you. One additional tid bit I'd like to know is relative speed.
In Java, abstract methods and classes are very fast. Interfaces require
extra indirection to find the corresponding method in the actual class.
Is this the case in .NET?
 
J

Jeffrey Palermo, MCAD.Net

Frank,
You know your design best and will ultimately make the decision of
which one to go with. Regarding "In fact, if you look at the .NET
framework, you won't find a single case of straight down (IDoSomething,
that's implemented by CDoSomething) encapsulation. ", I looked and
found one quite easily.
http://msdn.microsoft.com/library/d...curityprincipalgenericprincipalclasstopic.asp
This is GenericPrincipal, which is what ASP.NET Page classes use for
the user object by default. The page class has the member "User",
which is IPrincipal so that I can create my own class _either_ by
inheriting from one of the bases they provide (which implement
IPrincipal) or creating my own custom class that implements IPrincipal
(which I favor).

If in your design, this pattern makes no sense, don't do it, but if the
interface/abstract class will be extended multiple times, binding to
the interface with a default implementation class will work and won't
hurt you in the future if you need to make an alternate implementation
in a class that may already have a base. If you only do the abstract
class, then you have put a restriction in place that the implementing
classes must use it as the base. You must decide if that is a
reasonable restriction. It might be.

Regarding performance differences between inheritence and interface
implementation, I don't know. I've never tested. Honestly, if I cared
about little performance differences like that, I'd probably favor
programming in assembly because I wouldn't tolerate the overall
slowness of .Net and the enormous memory consumption in relation to
Assembly (or even C++). With abstraction comes a performance hit. But
it is a trade-off between performance and maintainability. I'm not
sure if there is any performance difference, but if it concerns you,
please do a test and let us know the result.

Best regards,
Jeffrey Palermo
http://www.jeffreypalermo.com
 
F

Frank Rizzo

Jeffrey said:
Regarding performance differences between inheritence and interface
implementation, I don't know. I've never tested. Honestly, if I cared
about little performance differences like that, I'd probably favor
programming in assembly because I wouldn't tolerate the overall
slowness of .Net and the enormous memory consumption in relation to
Assembly (or even C++). With abstraction comes a performance hit. But
it is a trade-off between performance and maintainability. I'm not
sure if there is any performance difference, but if it concerns you,
please do a test and let us know the result.


The reason I care about speed in this case is because it will be the
most used structure in the app being invoked continuously 24x7. So
while the performance hit on a single instantiation maybe negligable,
the effect on the overall operation maybe rather large. For instance,
processing 5 million transaction a day vs 4 million transactions a day
would be huge. That's why I care about speed.
 
J

Jon Skeet [C# MVP]

Frank Rizzo said:
The reason I care about speed in this case is because it will be the
most used structure in the app being invoked continuously 24x7. So
while the performance hit on a single instantiation maybe negligable,
the effect on the overall operation maybe rather large. For instance,
processing 5 million transaction a day vs 4 million transactions a day
would be huge. That's why I care about speed.

And do you have any evidence to suggest that instantiation is the
bottleneck, and that the performance you get when coding it in the most
elegant and readable way isn't already good enough?
 
H

Helge Jensen

Frank said:
would be huge. That's why I care about speed.

Run a test, it is very dangerous to second-guess performance in
high-level languages. Even more so in runtime-dependant and jit-compiled
ones.

Besides, any other processing you do to these object will have to be
*very* simple indeed for the virtual-dispatch to take up much of the
processing time.

Remember, optimization cannot save more cpu-cycles than you spend
unoptimized, so do your optimization where lots of time is spent.
 
F

Frank Rizzo

Jon said:
And do you have any evidence to suggest that instantiation is the
bottleneck,

No, I don't have any evidence, since I don't have the structure just
yet. I am in the design stage. The reason that I brought it up is
because that's the case in Java: Interface require an additional level
of indirection. I do not know whether this is the case in .NET, but
given that it makes sense and the 2 frameworks are similar, I am worried
about it.
and that the performance you get when coding it in the most
elegant and readable way isn't already good enough?

I don't believe coding it the interface way is any readable or elegant.
 
F

Frank Rizzo

Helge said:
Run a test, it is very dangerous to second-guess performance in
high-level languages. Even more so in runtime-dependant and jit-compiled
ones.
Besides, any other processing you do to these object will have to be
*very* simple indeed for the virtual-dispatch to take up much of the
processing time.
Remember, optimization cannot save more cpu-cycles than you spend
unoptimized, so do your optimization where lots of time is spent.

I agree. This is the place where most of the time would be spent.
Unfortunately, I can't run a test because I don't yet have anything: I
am in the design stage.
 
J

Jeff Louie

Well... Unfortunately I disagree with this rule. Realize that an
interface in C# is
conceptually equivalent to a pure virtual class in C++. Therefore an
interface
simply represents a abstract IS_A relationship. It "can be" or "looks
like", but it
still represents an IS_A relationship.

Regards,
Jeff
But, my rule has been what I learned in Intro to OOP 10
years ago. Interface is a "can-be", while Class is a "is-a".
 
J

Jon Skeet [C# MVP]

Frank Rizzo said:
No, I don't have any evidence, since I don't have the structure just
yet. I am in the design stage. The reason that I brought it up is
because that's the case in Java: Interface require an additional level
of indirection. I do not know whether this is the case in .NET, but
given that it makes sense and the 2 frameworks are similar, I am worried
about it.

Yes, it requires an extra level of indirection. The time taken for that
indirection is almost certainly going to be insignificant for anything
other than the tightest loops.

Architectural performance (how many round-trips you need to make,
database locking etc) is going to be a *far* bigger factor in
performance than micro-optimisation like this.
I don't believe coding it the interface way is any readable or elegant.

Ah, there we disagree. I believe that coding to an interface makes it
very clear what any one caller actually needs. A single class may
implement multiple interfaces to be used by multiple callers in
different ways - making each caller use just the interface makes it
easy to swap implementations, and to see what's using what.
 

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