tags:

views:

210

answers:

7

Should a class implement an interface always in order to enforce a sort of 'contract' on the class?

When shouldn't a class implement an interface?

Edit: Meaning, when is it worthwhile to have a class implement an interface? Why not have a class just have public members and private members with various accessor/setter functions?

(Note: Not talking about COM)

+16  A: 

No, an interface is not always required - the public members of the class already form a contract.

An interface is useful when you want to be able to exchange one class for another when both offer similar functionality. Using an interface allows you to decouple the contract from the specific implementation. However this decoupling is not always necessary or useful.

Many classes in the .NET framework do not implement any interfaces.

Mark Byers
The primary reason why you might want to have an interface for a class without planning to use that interface for other concrete classes is for unit testing. This is frequently useful to help isolate dependencies and stub/mock interfaces to inject stimuli and/or sense behavior.
Dan Bryant
+4  A: 

Only use an interface when it is needed.
That is: when you want to have different implementations for a certain abstraction.

When, in the future, it seems that it would be better to have an interface for a specific class (because for instance, you want to have another implementation for the same concept), then you can always create the interface from your existing class. (ExtractInterface refactoring)

Frederik Gheysels
It's also helpful to have an interface if the class is sufficiently 'side-effecty' and you want to be able to run code without the side effects. For instance, suppose you have a class for a device with a method `SelfDestruct()`. You will want to test that the logic properly triggers `SelfDestruct()` under the right circumstances (ideally in a unit test, but perhaps also as part of integration testing). However, you don't want to actually destroy the prototype. An interface and appropriate stub can help connect your code to a safer class that isn't hooked up to high explosives.
Dan Bryant
+2  A: 

This once again comes down to what he means by "interface". There is some ambiguity between the term interface and Interface. When the term Interface is used it means an object that has no method declarations. When the term interface is used it means that you utilize a pre-defined set of functions (whether they be implemented or not) and override them with your logic if necessary. An example would be:

abstract class Animal
class Dog extends Animal

In this instance Animal == interface (or contract) for Dog

interface Measurable
class Cup implements Measurable

In this instance Measurable == Interface for Cup

Woot4Moo
Good Point. An Interace in C++ is just an abstract class.
Shiftbit
+2  A: 

Interfaces become more necessary when you are doing unit testing, but it all depends on the context of your development. As Mark said, an interface IS the contract and implementing it forces you to adhere to the "rules" of that contract.

If you are trying to enforce the implementation of certain methods, then using an interface is perfect for that.

There are some nice examples here:

MaseBase
+1  A: 

You may not always want an interface. Consider you can accomplish similar tasks with a delegate. In Java I used the Runnable Interface for multithreaded applications. Now that I program in .NET I rely a lot on delegates to accomplish my mulithreaded applications. This article helps explains the need for an Delegate vs an Interface.

When to Use Delegates Instead of Interfaces (C# Programming Guide)

Delegates provide a little more flexibility as in Java I found that any task that I accomplished in C with a function pointer now required incasulation with an an Interface.

Although there are lots of circumstances for an Interface. Consider IEnumerable as it allows you to iterate over various collection without needing to understand how the underlying code works. Interfaces are great for when you need need to exchange one class for another but require a similar Interface. ICollection and IList provide a set of similar functionality to accomplish the operation on a collection without worrying about the specifics.

If you would like to better understand Interfaces I suggest you read "Head First Design Patterns".

Shiftbit
+1  A: 

A class should not implement interface/s unless you want to tell other parts of your program - "This class can do these things (but not specify how exactly it does what it does)".
When would you want to do that?
For example, say you have a game in which you have animals.. And say whenever an animal sees a human it makes it's sound (be it a bark, a roar etc.).
If all animals will implement interface IMakeSound in which there is a method called MakeSound, you will not have to care about what kind of animal it is that should make that sound.. All you'll have to do is to use the "IMakeSound" part of the animal, and call it's method.
I should add that when one reads in a class declaration that it implements a certain interface, it tells him a lot about that class, which is another benefit.

Oren A
+2  A: 

An interface, here meaning the code construct and not the design abstraction, supports a basic principle of code design called "loose coupling". There are some more derived principles that tell you HOW code should be loosely coupled, but in the main, loose coupling helps allow changes to code to affect as small an area of the codebase as possible.

Consider, for example, a calculation of some arbitrary complexity. This calculation is used by 6 different classes, and so to avoid duplicating code, the calculation is encapsulated in its own class, Calculator. The 6 classes each contain a reference to a Calculator. Now, say that your customer comes to you and says that in one usage of Calculator, if certain conditions are met, a different calculation should be used instead. You might be tempted to simply put these two rules (usage rule and business rule) and the new calculation algorithm into the Calculator class, but if you do so, then two things will happen; first, you make Calculator aware of some implementation details (how it's used) outside of its scope, that it doesn't need to know and that can change again later. Second, the other 5 classes that use Calculator, which were working just fine as-is, will have to be recompiled since they reference the changed class, and will have to be tested to ensure you didn't break their functionality by changing the one for the 6th class.

The "proper" solution to this is an interface. By defining an interface ICalculator, that exposes the method(s) called by the other classes, you break the concrete dependence of the 6 classes on the specific class Calculator. Now, each of the 6 classes can have a reference to an ICalculator. On 5 of these classes, you provide the same Calculator class they've always had and work just fine with. On the 6th, you provide a special calculator that knows the additional rules. If you had done this from the beginning, you wouldn't have had to touch the other 5 classes to make the change to the 6th.

The basic point is, classes should not have to know the exact nature of other objects they depend on; they should instead only have to know what that object will do for them. By abstracting what the object DOES from what the object IS, multiple objects can do similar things, and the classes that require those things don't have to know the difference.

Loose coupling, along with "high cohesion" (objects should usually be specialists that know how to do a small, very highly-related set of tasks), is the foundation for most of the software design patterns you'll see as you progress into software development theory.

In contrast to a couple of answers, there are design methodologies (e.g. SOLID) that state that you should ALWAYS set up dependencies as abstractions, like an abstract base class or an interface, and NEVER have one class depend upon another concrete class. The logic here is that in commercial software development, the initial set of requirements for an application is very small, but it is a safe assumption, if not a guarantee, that the set of requirements will grow and change. When that happens, the software must grow. Creating even smaller applications according to strict design principles allows extending the software without causing the problems that are a natural consequence of bad design (large classes with lots of code, changes to one class affecting others in unpredictable ways, etc). However, the art of software development, and the time and money constraints of same, are such that you can (and have to) be smart and say "from what I know of the way this system will grow, this is an area that needs to be well-designed to allow adaptation, while this other section will almost surely never change". If those assumptions change, you can go back and refactor areas of code you designed very simply to be more robust before you extend that area. But, you have to be willing and able to go back and change the code after it's first implemented.

KeithS