Interface vs Base class
Asked Answered
D

38

838

When should I use an interface and when should I use a base class?

Should it always be an interface if I don't want to actually define a base implementation of the methods?

If I have a Dog and Cat class. Why would I want to implement IPet instead of PetBase? I can understand having interfaces for ISheds or IBarks (IMakesNoise?), because those can be placed on a pet by pet basis, but I don't understand which to use for a generic Pet.

Distiller answered 11/9, 2008 at 15:20 Comment(3)
Just a point I think you should take into consideration - interfaces have can pose several limits you may not be aware of until very late stages. For example, with .NET you cannot serialize an interface member variable, so if you have a class Zoo and a member variable array of IAnimals you will not be able to serialize Zoo (and that means writing WebServices or other things requiring a serialization would be a pain).Northey
This question might help to understand concept of interfaces. https://mcmap.net/q/23159/-why-to-use-interfaces-multiple-inheritance-vs-interfaces-benefits-of-interfaces/1055241Ashmore
I am just curious. I met in the CLR via C# the following excerpt: I tend to prefer using the interface technique over the base type technique because the base type technique doesn’t allow the developer to choose the base type that works best in a particular situation.. I can not grasp what is meant in the excerpt. We can create a few base types and create a derived type for any of them, so a developer can choose a base type. Could someone explain, please, what am I missing? I believe it can be a part of this question. Or should I post another one about the specific excerpt?Zephyr
D
547

Let's take your example of a Dog and a Cat class, and let's illustrate using C#:

Both a dog and a cat are animals, specifically, quadruped mammals (animals are waaay too general). Let us assume that you have an abstract class Mammal, for both of them:

public abstract class Mammal

This base class will probably have default methods such as:

  • Feed
  • Mate

All of which are behavior that have more or less the same implementation between either species. To define this you will have:

public class Dog : Mammal
public class Cat : Mammal

Now let's suppose there are other mammals, which we will usually see in a zoo:

public class Giraffe : Mammal
public class Rhinoceros : Mammal
public class Hippopotamus : Mammal

This will still be valid because at the core of the functionality Feed() and Mate() will still be the same.

However, giraffes, rhinoceros, and hippos are not exactly animals that you can make pets out of. That's where an interface will be useful:

public interface IPettable
{
    IList<Trick> Tricks{get; set;}
    void Bathe();
    void Train(Trick t);
}

The implementation for the above contract will not be the same between a cat and dog; putting their implementations in an abstract class to inherit will be a bad idea.

Your Dog and Cat definitions should now look like:

public class Dog : Mammal, IPettable
public class Cat : Mammal, IPettable

Theoretically you can override them from a higher base class, but essentially an interface allows you to add on only the things you need into a class without the need for inheritance.

Consequently, because you can usually only inherit from one abstract class (in most statically typed OO languages that is... exceptions include C++) but be able to implement multiple interfaces, it allows you to construct objects in a strictly as required basis.

Dextrocular answered 11/9, 2008 at 15:20 Comment(6)
I don't think it is that simple. You have slightly changed the question (requirements) so that interface makes more sense. You should always ask yourself whether you are defining a contract (interface) or a shared implementation (base class).Bilyeu
The interface is a contract. You're only exposing the part of the contract that a service requires. If you have a 'PettingZoo', you certainly don't want to expose 'Mate'-ing to the user!Candiscandle
@David Touche, although I did it to better illustrate what an interface is for and what an abstract class is for vis-a-vis his understanding. A dog and a cat does not appear to be a rigid requirement!Dextrocular
@DaveRook LOL! Hence my qualifier "probably". Feed and Mate looks valid, maybe Hunt should be in another interface like IPredator or ICarnivore :DDextrocular
It should be noted that in interpreted, JIT-ing environments (particularly the JVM), virtual method calls are significantly faster than interface method calls, depending on the context. I emphasize "context" because the JVM can often optimize away the slow method lookups. (e.g., if a list of interface inheritors tend to be instances of the same class. This sadly makes benchmarking a tad difficult.) If you're trying to optimize something performance sensitive, and only then, you should consider this.Belaud
Also, an interface allows for a pet rock, allowing it to be bathed and be taught tricks, but feeding and mating would not be supported because that would be ridiculous for a rock.Tallulah
S
155

Well, Josh Bloch said himself in Effective Java 2d:

Prefer interfaces over abstract classes

Some main points:

  • Existing classes can be easily retrofitted to implement a new interface. All you have to do is add the required methods if they don’t yet exist and add an implements clause to the class declaration.

  • Interfaces are ideal for defining mixins. Loosely speaking, a mixin is a type that a class can implement in addition to its “primary type” to declare that it provides some optional behavior. For example, Comparable is a mixin interface that allows a class to declare that its instances are ordered with respect to other mutually comparable objects.

  • Interfaces allow the construction of nonhierarchical type frameworks. Type hierarchies are great for organizing some things, but other things don’t fall neatly into a rigid hierarchy.

  • Interfaces enable safe, powerful functionality enhancements via the wrap- per class idiom. If you use abstract classes to define types, you leave the programmer who wants to add functionality with no alternative but to use inheritance.

Moreover, you can combine the virtues of interfaces and abstract classes by providing an abstract skeletal implementation class to go with each nontrivial interface that you export.

On the other hand, interfaces are very hard to evolve. If you add a method to an interface it'll break all of it's implementations.

PS.: Buy the book. It's a lot more detailed.

Steels answered 11/9, 2008 at 15:20 Comment(4)
Whenever a change needs to be made to an interface, the non-breaking way to do so is to create a new interface that inherits from the old one. This preserves existing implementations and lets you do whatever you wish in the new one.Trapezius
we have "Interface Segregation Principle". This principle teaches us to take care how we write our interfaces.When we write our interfaces we should take care to add only methods that should be there. If we add methods that should not be there the classes implementing the interface will have to implement those methods as well. For example if we create an interface called Worker and add a method lunch break, all the workers will have to implement it. What if the worker is a robot?As a conclusion Interfaces containing methods that are not specific to it are called polluted or fat interfaces.Darnell
Since Java 8, Default methods enable you to add new functionality to the interfaces and ensure backward compatibility for existing classes which implement that interface. Default methods are invoked by default, if they are not overridden in the implementing class. All implementing class can either override default methods or they can directly call them using instance.defaultMethod()Papillary
Also worth noting that with the introduction of those default methods, Java now (...as of 2013) allows for multiple inheritance of type and behavior. It still does not allow for inheritance of state (fields), which may be one of the most defining differences left between an interface and an abstract base class in Java. Without this difference, anything done in class could be done in interface.Lent
B
147

Interfaces and base classes represent two different forms of relationships.

Inheritance (base classes) represent an "is-a" relationship. E.g. a dog or a cat "is-a" pet. This relationship always represents the (single) purpose of the class (in conjunction with the "single responsibility principle").

Interfaces, on the other hand, represent additional features of a class. I'd call it an "is" relationship, like in "Foo is disposable", hence the IDisposable interface in C#.

Butler answered 11/9, 2008 at 15:20 Comment(3)
Out of all the answers, this one gives the best mixture of brevity without loss of claritySculpturesque
Someone once told me to use an interface when there is a "has-a" relation. I'm not sure if that's always true though; My laptop has a screen, so should laptop implement IScreen, or have a Screen property? The latter seems more natural to me.Molli
@berend funny that you write that because the screens are implemented via interfaces - VGA, HDMI etcRutile
F
114

Modern style is to define IPet and PetBase.

The advantage of the interface is that other code can use it without any ties whatsoever to other executable code. Completely "clean." Also interfaces can be mixed.

But base classes are useful for simple implementations and common utilities. So provide an abstract base class as well to save time and code.

Favourite answered 11/9, 2008 at 15:20 Comment(8)
have your cake and eat it too!Femininity
yup yup! And with modern IDE's it will even write the boiler-plate code for you (and some languages don't even need THAT)Favourite
An interface defines how other classes can use your code. A base class helps implementers to implement your interface. Two different things for two different purposes.Mosira
I find this doubtful: is this .NET advice? Do you have a reference? In principle there are just a few reasons why you would create a "Base" class, typically delegation is preferable to inheritance.Aprilette
For example, to create a thread class in Java, you may either extend java.lang.Thread or implement java.lang.Runnable. To create an RMI server, you may either extend java.rmi.server.UnicastRemoteObject or implement java.rmi.Remote, and call UnicastRemoteObject.exportObject().Damage
There is nothing "modern" here. Base class and interface with the same API is simply redundant. You may use this approach it in some cases but you should not generalise!Gavial
The most supported comment to the second supported answer actually disagrees with the answer itself, interesting. I must say I see many examples of interface and base class co-exist. In that sense it is the "modern" way. For example, in MVVM pattern, there is actually ViewModelBase class which implements INotifyPropertyChanged. But when my colleague asked me why did I have the base class, instead of implementing the interface in every view model, I don't know how to convince himRosemari
Correct. It is not a question of 1 or the other. They exist to address 2 very different problems. Interfaces are contracts that an implementing class must address. They have found recent favour (sometimes fanatically) for IoC and TDD aspects. Abstract/Base classes serve to group hierarchically common logic and properties. It reduces duplicated code which in turn increases a solutions maintainability and makes it less prone to error.Wooldridge
A
68

Interfaces

  • Most languages allow you to implement multiple interfaces
  • Modifying an interface is a breaking change. All implementations need to be recompiled/modified.
  • All members are public. Implementations have to implement all members.
  • Interfaces help in Decoupling. You can use mock frameworks to mock out anything behind an interface
  • Interfaces normally indicate a kind of behavior
  • Interface implementations are decoupled / isolated from each other

Base classes

  • Allows you to add some default implementation that you get for free by derivation (From C# 8.0 by interface you can have default implementation)
  • Except C++, you can only derive from one class. Even if could from multiple classes, it is usually a bad idea.
  • Changing the base class is relatively easy. Derivations do not need to do anything special
  • Base classes can declare protected and public functions that can be accessed by derivations
  • Abstract Base classes can't be mocked easily like interfaces
  • Base classes normally indicate type hierarchy (IS A)
  • Class derivations may come to depend on some base behavior (have intricate knowledge of parent implementation). Things can be messy if you make a change to the base implementation for one guy and break the others.
Albrecht answered 11/9, 2008 at 15:20 Comment(1)
Note: the framework design guidelines recommend using base classes (as opposed to interfaces) because they version better. Adding a new method to an abstract base class in vNext is a non-breaking change..Albrecht
D
62

In general, you should favor interfaces over abstract classes. One reason to use an abstract class is if you have common implementation among concrete classes. Of course, you should still declare an interface (IPet) and have an abstract class (PetBase) implement that interface.Using small, distinct interfaces, you can use multiples to further improve flexibility. Interfaces allow the maximum amount of flexibility and portability of types across boundaries. When passing references across boundaries, always pass the interface and not the concrete type. This allows the receiving end to determine concrete implementation and provides maximum flexibility. This is absolutely true when programming in a TDD/BDD fashion.

The Gang of Four stated in their book "Because inheritance exposes a subclass to details of its parent's implementation, it's often said that 'inheritance breaks encapsulation". I believe this to be true.

Dmitri answered 11/9, 2008 at 15:20 Comment(4)
Yeesh. Personally, I believe this is ass backwards. Interfaces should hold the bare minimum functionality for a type, and base classes should provide a rich framework upon which customization can be built. Put that in an interface and you just made it very hard to implement.Guise
Nobody said your interfaces need to be huge. Smaller, multiple interfaces and richer base classes make a great API.Dmitri
Is it just me, or do most "common worker" classes share a common implementation? In that context it goes against your general rule of favoring interfaces. I would restate your generalization into 2 generalizations: Those common classes that contain no or little logic should implement an interface. Those common classes that contain a "decent" amount of logic should derive from a base class (since most likely they will share functionality).Liman
@Dmitri "Interfaces allow the maximum amount of flexibility and portability of types across boundaries" please elaborate this statement.Protein
R
52

This is pretty .NET specific, but the Framework Design Guidelines book argues that in general classes give more flexibility in an evolving framework. Once an interface is shipped, you don't get the chance to change it without breaking code that used that interface. With a class however, you can modify it and not break code that links to it. As long you make the right modifications, which includes adding new functionality, you will be able to extend and evolve your code.

Krzysztof Cwalina says on page 81:

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 guidelines, 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.

That being said there certainly is a place for interfaces. As a general guideline always provide an abstract base class implementation of an interface if for nothing else as an example of a way to implement the interface. In the best case that base class will save a lot of work.

Raffish answered 11/9, 2008 at 15:20 Comment(1)
found this as I started my quest to understand why this page learn.microsoft.com/en-us/dotnet/standard/library-guidance/… advises leveraging abstract base classes over interfaces (not sure if that recommendation on the page is for every package in general)Guam
S
20

Juan,

I like to think of interfaces as a way to characterize a class. A particular dog breed class, say a YorkshireTerrier, may be a descended of the parent dog class, but it is also implements IFurry, IStubby, and IYippieDog. So the class defines what the class is but the interface tells us things about it.

The advantage of this is it allows me to, for example, gather all the IYippieDog's and throw them into my Ocean collection. So now I can reach across a particular set of objects and find ones that meet the criteria I am looking at without inspecting the class too closely.

I find that interfaces really should define a sub-set of the public behavior of a class. If it defines all the public behavior for all the classes that implement then it usually does not need to exist. They do not tell me anything useful.

This thought though goes counter to the idea that every class should have an interface and you should code to the interface. That's fine, but you end up with a lot of one to one interfaces to classes and it makes things confusing. I understand that the idea is it does not really cost anything to do and now you can swap things in and out with ease. However, I find that I rarely do that. Most of the time I am just modifying the existing class in place and have the exact same issues I always did if the public interface of that class needs changing, except I now have to change it in two places.

So if you think like me you would definitely say that Cat and Dog are IPettable. It is a characterization that matches them both.

The other piece of this though is should they have the same base class? The question is do they need to be broadly treated as the same thing. Certainly they are both Animals, but does that fit how we are going to use them together.

Say I want to gather all Animal classes and put them in my Ark container.

Or do they need to be Mammals? Perhaps we need some kind of cross animal milking factory?

Do they even need to be linked together at all? Is it enough to just know they are both IPettable?

I often feel the desire to derive a whole class hierarchy when I really just need one class. I do it in anticipation someday I might need it and usually I never do. Even when I do, I usually find I have to do a lot to fix it. That’s because the first class I am creating is not the Dog, I am not that lucky, it is instead the Platypus. Now my entire class hierarchy is based on the bizarre case and I have a lot of wasted code.

You might also find at some point that not all Cats are IPettable (like that hairless one). Now you can move that Interface to all the derivative classes that fit. You will find that a much less breaking change that all of a sudden Cats are no longer derived from PettableBase.

Soup answered 11/9, 2008 at 15:20 Comment(0)
P
19

Here is the basic and simple definiton of interface and base class:

  • Base class = object inheritance.
  • Interface = functional inheritance.

cheers

Procreant answered 11/9, 2008 at 15:20 Comment(0)
E
15

It is explained well in this Java World article.

Personally, I tend to use interfaces to define interfaces - i.e. parts of the system design that specify how something should be accessed.

It's not uncommon that I will have a class implementing one or more interfaces.

Abstract classes I use as a basis for something else.

The following is an extract from the above mentioned article JavaWorld.com article, author Tony Sintes, 04/20/01


Interface vs. abstract class

Choosing interfaces and abstract classes is not an either/or proposition. If you need to change your design, make it an interface. However, you may have abstract classes that provide some default behavior. Abstract classes are excellent candidates inside of application frameworks.

Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class.

Many developers forget that a class that defines an abstract method can call that method as well. Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.

Class vs. interface

Some say you should define all classes in terms of interfaces, but I think recommendation seems a bit extreme. I use interfaces when I see that something in my design will change frequently.

For example, the Strategy pattern lets you swap new algorithms and processes into your program without altering the objects that use them. A media player might know how to play CDs, MP3s, and wav files. Of course, you don't want to hardcode those playback algorithms into the player; that will make it difficult to add a new format like AVI. Furthermore, your code will be littered with useless case statements. And to add insult to injury, you will need to update those case statements each time you add a new algorithm. All in all, this is not a very object-oriented way to program.

With the Strategy pattern, you can simply encapsulate the algorithm behind an object. If you do that, you can provide new media plug-ins at any time. Let's call the plug-in class MediaStrategy. That object would have one method: playStream(Stream s). So to add a new algorithm, we simply extend our algorithm class. Now, when the program encounters the new media type, it simply delegates the playing of the stream to our media strategy. Of course, you'll need some plumbing to properly instantiate the algorithm strategies you will need.

This is an excellent place to use an interface. We've used the Strategy pattern, which clearly indicates a place in the design that will change. Thus, you should define the strategy as an interface. You should generally favor interfaces over inheritance when you want an object to have a certain type; in this case, MediaStrategy. Relying on inheritance for type identity is dangerous; it locks you into a particular inheritance hierarchy. Java doesn't allow multiple inheritance, so you can't extend something that gives you a useful implementation or more type identity.

Ebonize answered 11/9, 2008 at 15:20 Comment(2)
+1. "Relying on inheritance for type identity is dangerous; it locks you into a particular inheritance hierarchy." That sentence perfectly describes my reasons for preferring interfaces.Frier
And beyond that, rather than extending, compose the implementation behind each method of your interface.Frier
R
12

Also keep in mind not to get swept away in OO (see blog) and always model objects based on behavior required, if you were designing an app where the only behavior you required was a generic name and species for an animal then you would only need one class Animal with a property for the name, instead of millions of classes for every possible animal in the world.

Rancidity answered 11/9, 2008 at 15:20 Comment(0)
I
12

I recommend using composition instead of inheritence whenever possible. Use interfaces but use member objects for base implementation. That way, you can define a factory that constructs your objects to behave in a certain way. If you want to change the behavior then you make a new factory method (or abstract factory) that creates different types of sub-objects.

In some cases, you may find that your primary objects don't need interfaces at all, if all of the mutable behavior is defined in helper objects.

So instead of IPet or PetBase, you might end up with a Pet which has an IFurBehavior parameter. The IFurBehavior parameter is set by the CreateDog() method of the PetFactory. It is this parameter which is called for the shed() method.

If you do this you'll find your code is much more flexible and most of your simple objects deal with very basic system-wide behaviors.

I recommend this pattern even in multiple-inheritence languages.

Isagoge answered 11/9, 2008 at 15:20 Comment(0)
B
11

Source: http://jasonroell.com/2014/12/09/interfaces-vs-abstract-classes-what-should-you-use/

C# is a wonderful language that has matured and evolved over the last 14 years. This is great for us developers because a mature language provides us with a plethora of language features that are at our disposal.

However, with much power becomes much responsibility. Some of these features can be misused, or sometimes it is hard to understand why you would choose to use one feature over another. Over the years, a feature that I have seen many developers struggle with is when to choose to use an interface or to choose to use an abstract class. Both have there advantages and disadvantages and the correct time and place to use each. But how to we decide???

Both provide for reuse of common functionality between types. The most obvious difference right away is that interfaces provide no implementation for their functionality whereas abstract classes allow you to implement some “base” or “default” behavior and then have the ability to “override” this default behavior with the classes derived types if necessary.

This is all well and good and provides for great reuse of code and adheres to the DRY (Don’t Repeat Yourself) principle of software development. Abstract classes are great to use when you have an “is a” relationship.

For example: A golden retriever “is a” type of dog. So is a poodle. They both can bark, as all dogs can. However, you might want to state that the poodle park is significantly different than the “default” dog bark. Therefor, it could make sense for you to implement something as follows:

public abstract class Dog
{
      public virtual void Bark()
      {
        Console.WriteLine("Base Class implementation of Bark");
      }
}

public class GoldenRetriever : Dog
{
   // the Bark method is inherited from the Dog class
}

public class Poodle : Dog
{
  // here we are overriding the base functionality of Bark with our new implementation
  // specific to the Poodle class
  public override void Bark()
  {
     Console.WriteLine("Poodle's implementation of Bark");
  }
}

// Add a list of dogs to a collection and call the bark method.

void Main()
{
    var poodle = new Poodle();
    var goldenRetriever = new GoldenRetriever();

    var dogs = new List<Dog>();
    dogs.Add(poodle);
    dogs.Add(goldenRetriever);

    foreach (var dog in dogs)
    {
       dog.Bark();
    }
}

// Output will be:
// Poodle's implementation of Bark
// Base Class implementation of Bark

// 

As you can see, this would be a great way to keep your code DRY and allow for the base class implementation be called when any of the types can just rely on the default Bark instead of a special case implementation. The classes like GoldenRetriever, Boxer, Lab could all could inherit the “default” (bass class) Bark at no charge just because they implement the Dog abstract class.

But I’m sure you already knew that.

You are here because you want to understand why you might want to choose an interface over an abstract class or vice versa. Well one reason you may want to choose an interface over an abstract class is when you don’t have or want to prevent a default implementation. This is usually because the types that are implementing the interface not related in an “is a” relationship. Actually, they don’t have to be related at all except for the fact that each type “is able” or has “the ablity” to do something or have something.

Now what the heck does that mean? Well, for example: A human is not a duck…and a duck is not a human. Pretty obvious. However, both a duck and a human have “the ability” to swim (given that the human passed his swimming lessons in 1st grade :) ). Also, since a duck is not a human or vice versa, this is not an “is a” realationship, but instead an “is able” relationship and we can use an interface to illustrate that:

// Create ISwimable interface
public interface ISwimable
{
      public void Swim();
}

// Have Human implement ISwimable Interface
public class Human : ISwimable

     public void Swim()
     {
        //Human's implementation of Swim
        Console.WriteLine("I'm a human swimming!");
     }

// Have Duck implement ISwimable interface
public class Duck: ISwimable
{
     public void Swim()
     {
          // Duck's implementation of Swim
          Console.WriteLine("Quack! Quack! I'm a Duck swimming!")
     }
}

//Now they can both be used in places where you just need an object that has the ability "to swim"

public void ShowHowYouSwim(ISwimable somethingThatCanSwim)
{
     somethingThatCanSwim.Swim();
}

public void Main()
{
      var human = new Human();
      var duck = new Duck();

      var listOfThingsThatCanSwim = new List<ISwimable>();

      listOfThingsThatCanSwim.Add(duck);
      listOfThingsThatCanSwim.Add(human);

      foreach (var something in listOfThingsThatCanSwim)
      {
           ShowHowYouSwim(something);
      }
}

 // So at runtime the correct implementation of something.Swim() will be called
 // Output:
 // Quack! Quack! I'm a Duck swimming!
 // I'm a human swimming!

Using interfaces like the code above will allow you to pass an object into a method that “is able” to do something. The code doesn’t care how it does it…All it knows is that it can call the Swim method on that object and that object will know which behavior take at run-time based on its type.

Once again, this helps your code stay DRY so that you would not have to write multiple methods that are calling the object to preform the same core function (ShowHowHumanSwims(human), ShowHowDuckSwims(duck), etc.)

Using an interface here allows the calling methods to not have to worry about what type is which or how the behavior is implemented. It just knows that given the interface, each object will have to have implemented the Swim method so it is safe to call it in its own code and allow the behavior of the Swim method be handled within its own class.

Summary:

So my main rule of thumb is use an abstract class when you want to implement a “default” functionality for a class hierarchy or/and the classes or types you are working with share a “is a” relationship (ex. poodle “is a” type of dog).

On the other hand use an interface when you do not have an “is a” relationship but have types that share “the ability” to do something or have something (ex. Duck “is not” a human. However, duck and human share “the ability” to swim).

Another difference to note between abstract classes and interfaces is that a class can implement one to many interfaces but a class can only inherit from ONE abstract class (or any class for that matter). Yes, you can nest classes and have an inheritance hierarchy (which many programs do and should have) but you cannot inherit two classes in one derived class definition (this rule applies to C#. In some other languages you are able to do this, usually only because of the lack of interfaces in these languages).

Also remember when using interfaces to adhere to the Interface Segregation Principle (ISP). ISP states that no client should be forced to depend on methods it does not use. For this reason interfaces should be focused on specific tasks and are usually very small (ex. IDisposable, IComparable ).

Another tip is if you are developing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class.

Hope this clears things up for some people!

Also if you can think of any better examples or want to point something out, please do so in the comments below!

Binion answered 11/9, 2008 at 15:20 Comment(0)
S
10

I have a rough rule-of-thumb

Functionality: likely to be different in all parts: Interface.

Data, and functionality, parts will be mostly the same, parts different: abstract class.

Data, and functionality, actually working, if extended only with slight changes: ordinary (concrete) class

Data and functionality, no changes planned: ordinary (concrete) class with final modifier.

Data, and maybe functionality: read-only: enum members.

This is very rough and ready and not at all strictly defined, but there is a spectrum from interfaces where everything is intended to be changed to enums where everything is fixed a bit like a read-only file.

Scrimshaw answered 11/9, 2008 at 15:20 Comment(0)
Q
7

Interfaces should be small. Really small. If you're really breaking down your objects, then your interfaces will probably only contain a few very specific methods and properties.

Abstract classes are shortcuts. Are there things that all derivatives of PetBase share that you can code once and be done with? If yes, then it's time for an abstract class.

Abstract classes are also limiting. While they give you a great shortcut to producing child objects, any given object can only implement one abstract class. Many times, I find this a limitation of Abstract classes, and this is why I use lots of interfaces.

Abstract classes may contain several interfaces. Your PetBase abstract class may implement IPet (pets have owners) and IDigestion (pets eat, or at least they should). However, PetBase will probably not implement IMammal, since not all pets are mammals and not all mammals are pets. You may add a MammalPetBase that extends PetBase and add IMammal. FishBase could have PetBase and add IFish. IFish would have ISwim and IUnderwaterBreather as interfaces.

Yes, my example is extensively over-complicated for the simple example, but that's part of the great thing about how interfaces and abstract classes work together.

Quadriplegic answered 11/9, 2008 at 15:20 Comment(0)
N
6

The case for Base Classes over Interfaces was explained well in the Submain .NET Coding Guidelines:

Base Classes vs. Interfaces An interface type is a partial description of a value, potentially supported by many object types. Use base classes instead of interfaces whenever possible. From a versioning perspective, classes are more flexible than interfaces. With a class, you can ship Version 1.0 and then in Version 2.0 add a new method to the class. As long as the method is not abstract, any existing derived classes continue to function unchanged.

Because interfaces do not support implementation inheritance, the pattern that applies to classes does not apply to interfaces. Adding a method to an interface is equivalent to adding an abstract method to a base class; any class that implements the interface will break because the class does not implement the new method. Interfaces are appropriate in the following situations:

  1. Several unrelated classes want to support the protocol.
  2. These classes already have established base classes (for example, some are user interface (UI) controls, and some are XML Web services).
  3. Aggregation is not appropriate or practicable. In all other situations, class inheritance is a better model.
Ninon answered 11/9, 2008 at 15:20 Comment(1)
I feel like this answer should get more attention. It goes against the grain of many answers, here. I wouldn't say I completely agree, but there are great points, here.Banket
S
5

One important difference is that you can only inherit one base class, but you can implement many interfaces. So you only want to use a base class if you are absolutely certain that you won't need to also inherit a different base class. Additionally, if you find your interface is getting large then you should start looking to break it up into a few logical pieces that define independent functionality, since there's no rule that your class can't implement them all (or that you can define a different interface that just inherits them all to group them).

Submersed answered 11/9, 2008 at 15:20 Comment(0)
S
4

Prefer interfaces over abstract classes

Rationale, the main points to consider [two already mentioned here] are :

  • Interfaces are more flexible, because a class can implement multiple interfaces. Since Java does not have multiple inheritance, using abstract classes prevents your users from using any other class hierarchy. In general, prefer interfaces when there are no default implementations or state. Java collections offer good examples of this (Map, Set, etc.).
  • Abstract classes have the advantage of allowing better forward compatibility. Once clients use an interface, you cannot change it; if they use an abstract class, you can still add behavior without breaking existing code. If compatibility is a concern, consider using abstract classes.
  • Even if you do have default implementations or internal state, consider offering an interface and an abstract implementation of it. This will assist clients, but still allow them greater freedom if desired [1].
    Of course, the subject has been discussed at length elsewhere [2,3].

[1] It adds more code, of course, but if brevity is your primary concern, you probably should have avoided Java in the first place!

[2] Joshua Bloch, Effective Java, items 16-18.

[3] http://www.codeproject.com/KB/ar...

Segment answered 11/9, 2008 at 15:20 Comment(0)
T
4

When I first started learning about object-oriented programming, I made the easy and probably common mistake of using inheritance to share common behavior - even where that behavior was not essential to the nature of the object.

To further build on an example much used in this particular question, there are lots of things that are petable - girlfriends, cars, fuzzy blankets... - so I might have had a Petable class that provided this common behavior, and various classes inheriting from it.

However, being petable is not part of the nature of any of these objects. There are vastly more important concepts that are essential to their nature - the girlfriend is a person, the car is a land vehicle, the cat is a mammal...

Behaviors should be assigned first to interfaces (including the default interface of the class), and promoted to a base class only if they are (a) common to a large group of classes that are subsets of a larger class - in the same sense that "cat" and "person" are subsets of "mammal".

The catch is, after you understand object-oriented design sufficiently better than I did at first, you'll normally do this automatically without even thinking about it. So the bare truth of the statement "code to an interface, not an abstract class" becomes so obvious you have a hard time believing anyone would bother to say it - and start trying to read other meanings into it.

Another thing I'd add is that if a class is purely abstract - with no non-abstract, non-inherited members or methods exposed to child, parent, or client - then why is it a class? It could be replaced, in some cases by an interface and in other cases by Null.

Tetrad answered 11/9, 2008 at 15:20 Comment(2)
A purely abstract class can provide default behaviors for methods. This is useful when your concrete classes will all share common methods that would be redundant to re-implement over and over.Ehman
https://mcmap.net/q/16136/-interface-vs-base-class speaks the same tone & another answer here https://mcmap.net/q/16136/-interface-vs-base-class adds the knowledge representation nuanceGuam
Z
3

Another option to keep in mind is using the "has-a" relationship, aka "is implemented in terms of" or "composition." Sometimes this is a cleaner, more flexible way to structure things than using "is-a" inheritance.

It may not make as much sense logically to say that Dog and Cat both "have" a Pet, but it avoids common multiple inheritance pitfalls:

public class Pet
{
    void Bathe();
    void Train(Trick t);
}

public class Dog
{
    private Pet pet;

    public void Bathe() { pet.Bathe(); }
    public void Train(Trick t) { pet.Train(t); }
}

public class Cat
{
    private Pet pet;

    public void Bathe() { pet.Bathe(); }
    public void Train(Trick t) { pet.Train(t); }
}

Yes, this example shows that there is a lot of code duplication and lack of elegance involved in doing things this way. But one should also appreciate that this helps to keep Dog and Cat decoupled from the Pet class (in that Dog and Cat do not have access to the private members of Pet), and it leaves room for Dog and Cat to inherit from something else--possibly the Mammal class.

Composition is preferable when no private access is required and you don't need to refer to Dog and Cat using generic Pet references/pointers. Interfaces give you that generic reference capability and can help cut down on the verbosity of your code, but they can also obfuscate things when they are poorly organized. Inheritance is useful when you need private member access, and in using it you are committing yourself to highly coupling your Dog and Cat classes to your Pet class, which is a steep cost to pay.

Between inheritance, composition, and interfaces there is no one way that is always right, and it helps to consider how all three options can be used in harmony. Of the three, inheritance is typically the option that should be used the least often.

Zwolle answered 11/9, 2008 at 15:20 Comment(0)
D
3

Conceptually, an interface is used to formally and semi-formally define a set of methods that an object will provide. Formally means a set of method names and signatures, and semi-formally means human readable documentation associated with those methods.

Interfaces are only descriptions of an API (after all, API stands for application programming interface), they can't contain any implementation, and it's not possible to use or run an interface. They only make explicit the contract of how you should interact with an object.

Classes provide an implementation, and they can declare that they implement zero, one or more Interfaces. If a class is intended to be inherited, the convention is to prefix the class name with "Base".

There is a distinction between a base class and an abstract base classes (ABC). ABCs mix interface and implementation together. Abstract outside of computer programming means "summary", that is "abstract == interface". An abstract base class can then describe both an interface, as well as an empty, partial or complete implementation that is intended to be inherited.

Opinions on when to use interfaces versus abstract base classes versus just classes is going to vary wildly based on both what you are developing, and which language you are developing in. Interfaces are often associated only with statically typed languages such as Java or C#, but dynamically typed languages can also have interfaces and abstract base classes. In Python for example, the distinction is made clear between a Class, which declares that it implements an interface, and an object, which is an instance of a class, and is said to provide that interface. It's possible in a dynamic language that two objects that are both instances of the same class, can declare that they provide completely different interfaces. In Python this is only possible for object attributes, while methods are shared state between all objects of a class. However, in Ruby, objects can have per-instance methods, so it's possible that the interface between two objects of the same class can vary as much as the programmer desires (however, Ruby doesn't have any explicit way of declaring Interfaces).

In dynamic languages the interface to an object is often implicitly assumed, either by introspecting an object and asking it what methods it provides (look before you leap) or preferably by simply attempting to use the desired interface on an object and catching exceptions if the object doesn't provide that interface (easier to ask forgiveness than permission). This can lead to "false positives" where two interfaces have the same method name, but are semantically different. However, the trade-off is that your code is more flexible since you don't need to over specify up-front to anticipate all possible uses of your code.

Delivery answered 11/9, 2008 at 15:20 Comment(0)
D
3

Don't use a base class unless you know what it means, and that it applies in this case. If it applies, use it, otherwise, use interfaces. But note the answer about small interfaces.

Public Inheritance is overused in OOD and expresses a lot more than most developers realize or are willing to live up to. See the Liskov Substitutablity Principle

In short, if A "is a" B then A requires no more than B and delivers no less than B, for every method it exposes.

Dewar answered 11/9, 2008 at 15:20 Comment(0)
T
3

Previous comments about using abstract classes for common implementation is definitely on the mark. One benefit I haven't seen mentioned yet is that the use of interfaces makes it much easier to implement mock objects for the purpose of unit testing. Defining IPet and PetBase as Jason Cohen described enables you to mock different data conditions easily, without the overhead of a physical database (until you decide it's time to test the real thing).

Trapezius answered 11/9, 2008 at 15:20 Comment(0)
E
2

I've found that a pattern of Interface > Abstract > Concrete works in the following use-case:

1.  You have a general interface (eg IPet)
2.  You have a implementation that is less general (eg Mammal)
3.  You have many concrete members (eg Cat, Dog, Ape)

The abstract class defines default shared attributes of the concrete classes, yet enforces the interface. For example:

public interface IPet{

    public boolean hasHair();

    public boolean walksUprights();

    public boolean hasNipples();
}

Now, since all mammals have hair and nipples (AFAIK, I'm not a zoologist), we can roll this into the abstract base class

public abstract class Mammal() implements IPet{

     @override
     public walksUpright(){
         throw new NotSupportedException("Walks Upright not implemented");
     }

     @override
     public hasNipples(){return true}

     @override
     public hasHair(){return true}

And then the concrete classes merely define that they walk upright.

public class Ape extends Mammal(){

    @override
    public walksUpright(return true)
}

public class Catextends Mammal(){

    @override
    public walksUpright(return false)
}

This design is nice when there are lots of concrete classes, and you don't want to maintain boilerplate just to program to an interface. If new methods were added to the interface, it would break all of the resulting classes, so you are still getting the advantages of the interface approach.

In this case, the abstract could just as well be concrete; however, the abstract designation helps to emphasize that this pattern is being employed.

Ehman answered 11/9, 2008 at 15:20 Comment(0)
P
2

By def, interface provides a layer to communicate with other code. All the public properties and methods of a class are by default implementing implicit interface. We can also define an interface as a role, when ever any class needs to play that role, it has to implement it giving it different forms of implementation depending on the class implementing it. Hence when you talk about interface, you are talking about polymorphism and when you are talking about base class, you are talking about inheritance. Two concepts of oops !!!

Posthaste answered 11/9, 2008 at 15:20 Comment(0)
O
2

Regarding C#, in some senses interfaces and abstract classes can be interchangeable. However, the differences are: i) interfaces cannot implement code; ii) because of this, interfaces cannot call further up the stack to subclass; and iii) only can abstract class may be inherited on a class, whereas multiple interfaces may be implemented on a class.

Oshinski answered 11/9, 2008 at 15:20 Comment(0)
W
2

I usually don't implement either until I need one. I favor interfaces over abstract classes because that gives a little more flexibility. If there's common behavior in some of the inheriting classes I move that up and make an abstract base class. I don't see the need for both, since they essentially server the same purpose, and having both is a bad code smell (imho) that the solution has been over-engineered.

Wilmington answered 11/9, 2008 at 15:20 Comment(0)
C
2

It depends on your requirements. If IPet is simple enough, I would prefer to implement that. Otherwise, if PetBase implements a ton of functionality you don't want to duplicate, then have at it.

The downside to implementing a base class is the requirement to override (or new) existing methods. This makes them virtual methods which means you have to be careful about how you use the object instance.

Lastly, the single inheritance of .NET kills me. A naive example: Say you're making a user control, so you inherit UserControl. But, now you're locked out of also inheriting PetBase. This forces you to reorganize, such as to make a PetBase class member, instead.

Catalonia answered 11/9, 2008 at 15:20 Comment(0)
M
1

When should I use an interface and when should I use a base class?

You should use interface if

  1. You have pure abstract methods and don't have non-abstract methods
  2. You don't have default implementation of non abstract methods (except for Java 8 language, where interface methods provides default implementation)
  3. If you are using Java 8, now interface will provide default implementation for some non-abstract methods. This will make interface more usable compared to abstract classes.

Have a look at this SE question for more details.

Should it always be an interface if I don't want to actually define a base implementation of the methods?

Yes. It's better and cleaner. Even if you have a base class with some abstract methods, let's base class extends abstract methods through interface. You can change interface in future without changing the base class.

Example in java:

abstract class PetBase implements IPet {
// Add all abstract methods in IPet interface and keep base class clean. 
   Base class will contain only non abstract methods and static methods.
}

If I have a Dog and Cat class. Why would I want to implement IPet instead of PetBase? I can understand having interfaces for ISheds or IBarks (IMakesNoise?), because those can be placed on a pet by pet basis, but I don't understand which to use for a generic Pet.

I prefer to have base class implement the interface.

 abstract class PetBase implements IPet {
 // Add all abstract methods in IPet
 }

 /*If ISheds,IBarks is common for Pets, your PetBase can implement ISheds,IBarks. 
  Respective implementations of PetBase can change the behaviour in their concrete classes*/

 abstract class PetBase implements IPet,ISheds,IBarks {
 // Add all abstract methods in respective interfaces
 }

Advantages:

  1. If I want to add one more abstract method in existing interfaces, I simple change interface without touching the abstract base class. If I want to change the contract, I will change interface & implementation classes without touching base class.

  2. You can provide immutability to base class through interface. Have a look at this article

Refer to this related SE question for more details:

How should I have explained the difference between an Interface and an Abstract class?

Mra answered 11/9, 2008 at 15:20 Comment(0)
D
1

Make a list of the things your objects must be, have, or do and the things your objects can (or might) be, have, or do. Must indicates your base types and can indicates your interfaces.

E.g., your PetBase must Breathe, and your IPet might DoTricks.

Analysis of your problem domain will help you define the precise hierarchy structure.

Dev answered 11/9, 2008 at 15:20 Comment(0)
L
1

Use Interfaces to enforce a contract ACROSS families of unrelated classes. For example, you might have common access methods for classes that represent collections, but contain radically different data i.e. one class might represent a result set from a query, while the other might represent the images in a gallery. Also, you can implement multiple interfaces, thus allowing you to blend (and signify) the capabilities of the class.

Use Inheritance when the classes bear a common relationship and therefore have a similair structural and behavioural signature, i.e. Car, Motorbike, Truck and SUV are all types of road vehicle that might contain a number of wheels, a top speed

Lavin answered 11/9, 2008 at 15:20 Comment(0)
S
1

An inheritor of a base class should have an "is a" relationship. Interface represents An "implements a" relationship. So only use a base class when your inheritors will maintain the is a relationship.

Stamina answered 11/9, 2008 at 15:20 Comment(0)
G
0

Thanks for answering by Jon Limjap but I want to add some explanation for concept of Interface and Abstract Base Classes

Interface Types vs. Abstract Base Classes

Adapted from the Pro C# 5.0 and the .NET 4.5 Framework book.

The interface type might seem very similar to an abstract base class. Recall that when a class is marked as abstract, it may define any number of abstract members to provide a polymorphic interface to all derived types. However, even when a class does define a set of abstract members, it is also free to define any number of constructors, field data, nonabstract members (with implementation), and so on. Interfaces, on the other hand, contain only abstract member definitions. The polymorphic interface established by an abstract parent class suffers from one major limitation in that only derived types support the members defined by the abstract parent. However, in larger software systems, it is very common to develop multiple class hierarchies that have no common parent beyond System.Object. Given that abstract members in an abstract base class apply only to derived types, we have no way to configure types in different hierarchies to support the same polymorphic interface. By way of example, assume you have defined the following abstract class:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

Given this definition, only members that extend CloneableType are able to support the Clone() method. If you create a new set of classes that do not extend this base class, you can’t gain this polymorphic interface. Also, you might recall that C# does not support multiple inheritance for classes. Therefore, if you wanted to create a MiniVan that is-a Car and is-a CloneableType, you are unable to do so:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

As you would guess, interface types come to the rescue. After an interface has been defined, it can be implemented by any class or structure, in any hierarchy, within any namespace or any assembly (written in any .NET programming language). As you can see, interfaces are highly polymorphic. Consider the standard .NET interface named ICloneable, defined in the System namespace. This interface defines a single method named Clone():

public interface ICloneable
{
object Clone();
}
Gally answered 11/9, 2008 at 15:20 Comment(0)
A
0

You should use a base class if there really isn't any reason for other developers to desire using their own base class in addition to your type's members and you foresee versioning issues (see http://haacked.com/archive/2008/02/21/versioning-issues-with-abstract-base-classes-and-interfaces.aspx).

If inheriting developers have any reason to use their own base class to implement your type's interface and you don't see the interface changing, then go with an interface. In this case, you can still throw in a default base class that implements the interface for sake of convenience.

Annulation answered 11/9, 2008 at 15:20 Comment(0)
L
0

There are other advantages to inheritance as well - such as the ability for a variable to be able to hold an object of either the parent class or the inherited class (without having to declare it as something generic, like "Object").

For example, in .NET WinForms, most UI components derive from System.Windows.Forms.Control, so a variable declared as that could "hold" just about any UI element - be it a button, a ListView, or what have you. Now, granted, you won't have access to all the properties or methods of the item, but you'll have all the basic stuff - and that can be useful.

Lh answered 11/9, 2008 at 15:20 Comment(1)
Your example doesnt support the concept. You can do the same thing with an interface. You don't just have to have a base class for that.Dmitri
A
0

Interfaces have the distinct advantage of being somewhat "hot swappable" for classes. Changing a class from one parent to another will often result in a great deal of work, but Interfaces can often be removed and changed without a great deal of effect on the implementation class. This is especially useful in cases where you have several narrow sets of behaviour that you "may" want a class to implement.

This works especially well in my field: game programming. Base classes can get bloated with tons of behaviours that "may" be needed by inherited objects. With interfaces different behaviours can be added or removed to objects easily and readily. For example, if I create an interface for "IDamageEffects" for objects that I want to reflect damage, then I can easily apply that to various game objects, and easily change my mind later. Say I design an initial class that I want to use for "static" decorative objects and I initially decide they are non-destructible. Later on, I may decide it would be more fun if they could blow up so I alter the class to implement the "IDamageEffects" interface. This is much easier to do than switching base classes or creating a new object hierarchy.

Assignment answered 11/9, 2008 at 15:20 Comment(0)
B
0

Use your own judgement and be smart. Don't always do what others (like me) are saying. You will hear "prefer interfaces to abstract classes" but it really depends. It depends what the class is.

In the above mentioned case where we have a hierarchy of objects, interface is a good idea. Interface helps to work with collections of these objects and it also helps when implementing a service working with any object of the hierarchy. You just define a contract for working with objects from the hierarchy.

On the other hand when you implement a bunch of services that share a common functionality you can either separate the common functionality into a complete separate class or you can move it up into a common base class and make it abstract so that nobody can instantiate the base class.

Also consider this how to support your abstractions over time. Interfaces are fixed: You release an interface as a contract for a set of functionality that any type can implement. Base classes can be extended over time. Those extensions become part of every derived class.

Bilyeu answered 11/9, 2008 at 15:20 Comment(0)
G
0

In addition to those comments that mention the IPet/PetBase implementation, there are also cases where providing an accessor helper class can be very valuable.

The IPet/PetBase style assumes that you have multiple implementations thus increasing the value of PetBase since it simplifies implementation. However, if you have the reverse or a blend of the two where you have multiple clients, providing a class help assist in the usage of the interface can reduce cost by making it easier to use an interface.

Goshen answered 11/9, 2008 at 15:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.