Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I used to create a lot of abstract classes / methods. Then I started using interfaces.

Now I am not sure if interfaces aren't making abstract classes obsolete.

You need a fully abstract class? Create an interface instead. You need an abstract class with some implementation in it? Create an interface, create a class. Inherit the class, implement the interface. An additional benefit is that some classes may not need the parent class, but will just implement the interface.

So, are abstract classes / methods obsolete?

share|improve this question
    
How about if your programming language of choice does not support interfaces? I seem to recall this is the case for C++. –  Bernard Jul 21 '11 at 15:48
6  
@Bernard: in C++, an abstract class is an interface in all but name. That they can also do more than 'pure' interfaces is not a disadvantage. –  gbjbaanb Jul 21 '11 at 15:51
    
@gbjbaanb: I suppose. I don't recall using them as interfaces, but rather to provide default implementations. –  Bernard Jul 21 '11 at 16:01
    
Interfaces are the "currency" of object references. Generally speaking they are the fundament of polymorphic behavior. Abstract classes serve a different purpose that deadalnix explained perfectly. –  jiggy Jul 21 '11 at 16:56
4  
Isn't this like saying "are modes of transport obsolete now we have cars?" Yeah, most of the time, you use a car. But whether you ever need anything other than a car or not, it wouldn't really be correct to say "I don't need to use modes of transport". An interface is much the same as an abstract class without any implementation, and with a special name, no? –  Jack V. Jul 22 '11 at 9:11
show 1 more comment

9 Answers

up vote 103 down vote accepted

No.

Interfaces cannot provide default implementation, abstract classes and method can. This is especially usefull to avoid code duplication in many cases.

This is also a really nice way to reduce sequential coupling. Without abstract method/classes, you cannot implement template method pattern. I suggest you look at this wikipedia article : http://en.wikipedia.org/wiki/Template_method_pattern

share|improve this answer
4  
+1 Spot on. Would have given this +10, if I could. –  wolfgangsz Jul 21 '11 at 15:55
3  
@deadalnix Template method pattern can be quite dangerous. You can easily end up with highly coupled code, and start hacking the code to extend the templated abstract class to handle "just one more case". –  quant_dev Jul 21 '11 at 17:20
7  
This seems more like an anti-pattern. You can get exactly the same thing with composition against an interface. Same thing applies to partial classes with some abstract methods. Rather then forcing client code to subclass and override them, you should have the implementation be injected. See: en.wikipedia.org/wiki/Composition_over_inheritance#Benefits –  back2dos Jul 21 '11 at 21:17
2  
This doesn't explain AT ALL how to reduce sequential coupling. I do agree that several ways exists to achieve this goal, but please, answer the problem you are talking about instead of blindly invoke some principle. You'll ends up doing cargo cult programming if you can't explain why this is related to the actual problem. –  deadalnix Jul 21 '11 at 21:27
2  
@deadalnix: Saying that sequential coupling is best reduced with the template pattern is cargo cult programming (using the state/strategy/factory pattern may just work as well), as is the assumption that it must always be reduced. Sequential coupling is often a mere consequence of exposing very fine grained control over something, meaning nothing but a trade-off. That still doesn't mean I can't write a wrapper that does not have sequential coupling using composition. In fact, it makes it a lot easier. –  back2dos Jul 22 '11 at 7:30
show 9 more comments

An abstract method exists so you can call it from within your base class but implement it in a derived class. So your base class knows:

public void DoTask()
{
    doSetup();
    DoWork();
    doCleanup();
}

protected abstract void DoWork();

That's a reasonably nice way to implement a hole in the middle pattern without the derived class knowing about the setup and cleanup activities. Without abstract methods, you'd have to rely on the derived class implementing DoTask and remembering to call base.DoSetup() and base.DoCleanup() all the time.

Edit

Also, thanks to deadalnix for posting a link to the Template Method Pattern, which is what I've described above without actually knowing the name. :)

share|improve this answer
    
That is one point I didn't consider. –  Boris Yankov Jul 21 '11 at 17:12
    
I do this all the time. Really useful. –  sixtyfootersdude Jul 21 '11 at 19:03
1  
+1, I prefer your answer to deadalnix'. Note that you can implement a template method in a more straight-forward way using delegates (in C#): public void DoTask(Action doWork) –  Joh Jul 25 '11 at 9:09
    
@Joh - true, but that's not necessarily as nice, depending on your API. If your base class is Fruit and your derived class is Apple, you want to call myApple.Eat(), not myApple.Eat((a) => howToEatApple(a)). Also, you don't want Apple to have to call base.Eat(() => this.howToEatMe()). I think it's cleaner just to override an abstract method. –  Scott Whitlock Jul 25 '11 at 14:03
    
@Scott Whitlock: Your example using apples and fruits is a bit too detached from reality to judge whether going for inheritance is preferable to delegates in general. Obviously, the answer is "it depends", so it leaves plenty of room for debates... Anyway, I find that template methods occur a lot during refactoring, e.g. when removing duplicate code. In such cases, I usually don't want to mess with the type hierarchy, and I prefer to stay away from inheritance. This kind of surgery is easier to do with lambdas. –  Joh Jul 27 '11 at 10:18
show 1 more comment

No, They are not obsolete.

In fact, there is an obscure but fundamental difference between Abstract Classes/Methods and Interfaces.

if the set of classes in which one of these has to be used have a common behaviour that they share (related classes, i mean), then go for Abstract classes/methods.

Example: clerk, Officer, Director -all these classes have CalculateSalary() in common, use abstract base classes.CalculateSalary() canbe differently implemented but there are certain other things like GetAttendance() for example which has a common definition in base class.

If your classes have nothing common(Unrelated classes, in the context chosen) in between them but has an action that is greatly different in implementation, then go for Interface.

Example: cow, bench, car, telesope-not related classes but Isortable can be there to sort them in an array.

This difference is usually ignored when approached from a polymorphic perspective. But I personally feel that there are situations where one is an apt than the other for the reason explained above.

share|improve this answer
add comment

In addition to the other good answers, there is a fundamental difference between interfaces and abstract classes that no one has mentioned specifically, namely that interfaces are far less reliable and therefore impose a much greater test burden than abstract classes. For example, consider this C# code:

public abstract class Frobber
{
    private Frobber() {}
    public abstract void Frob(Frotz frotz);
    private class GreenFrobber : Frobber
    { ... }
    private class RedFrobber : Frobber
    { ... }
    public static Frobber GetFrobber(bool b) { ... } // return a green or red frobber
}

public sealed class Frotz
{
    public void Frobbit(Frobber frobber)
    {
         ...
         frobber.Frob(this);
         ...
    }
}

I am guaranteed that there are only two code paths I need to test. The author of Frobbit can rely on the fact that the frobber is either red or green.

If instead we say:

public interface IFrobber
{
    void Frob(Frotz frotz);
}
public class GreenFrobber : IFrobber
{ ... }
public class RedFrobber : Frobber
{ ... }

public sealed class Frotz
{
    public void Frobbit(IFrobber frobber)
    {
         ...
         frobber.Frob(this);
         ...
    }
}

I now know absolutely nothing about the effects of that call to Frob there. I need to be sure that all the code in Frobbit is robust against any possible implementation of IFrobber, even implementations by people who are incompetent (bad) or actively hostile to me or my users (far worse).

Abstract classes allow you to avoid all these problems; use them!

share|improve this answer
1  
The problem you speak of should be solved by using algebraic data types, rather than bending classes to a point where they violate the open/closed principle. –  back2dos Jul 21 '11 at 21:58
    
@back2dos: Your assumption seems to be that the open-closed principle is a good principle. Though there are certainly domains in which that principle describes desirable behaviour, in many domains the idea that you have no clue what behaviour a given chunk of code is going to have when you invoke it is absolutely anathema to robustness, security and correctness, all of which I value much higher than adherence to some moral principle about what code "should" be like. –  Eric Lippert Jul 21 '11 at 22:06
1  
Firstly, I never said it is good or moral. You put that in my mouth. Secondly (being my actual point): It's nothing but a poor excuse for a missing language feature. Lastly, there's a solution without abstract classes: pastebin.com/DxEh8Qfz. In contrast to that, your approach uses nested and abstract classes, throwing all but the code requiring the safety together into a big ball of mud. There is no good reason why RedFrobber or GreenFrobber should be tied to the constraints you want to enforce. It increases coupling and locks in many decisions without any benefit. –  back2dos Jul 22 '11 at 7:17
1  
Saying that abstract methods are obsolete is wrong with no doubt, but claiming on the other hand that they should be preferred over interfaces is misguiding. They are simply a tool for solving different problems than interfaces. –  Groo Jul 22 '11 at 9:37
2  
"there is a fundamental difference [...] interfaces are far less reliable [...] than abstract classes". I disagree, the difference you have illustrated in your code relies on access restrictions, which I don't think have any reason to differ significantly between interfaces and abstract classes. It may be so in C#, but the question is language-agnostic. –  Joh Jul 25 '11 at 9:15
show 6 more comments

You say it yourself:

You need an abstract class with some implementation in it? Create an interface, create a class. Inherit the class, implement the interface

that sounds a lot of work compared to 'inherit the abstract class'. You can make work for yourself by approaching code from a 'purist' view, but I find I have enough to do already without trying to add to my workload for no practical benefit.

share|improve this answer
    
Not to mention that if the class doesn't inherit the interface (which was not mentioned it should), you have to write forwarding functions in some languages. –  Sjoerd Jul 21 '11 at 17:25
    
Umm, the additional "Lot of work" you mentioned is that you created an interface and had the classes implement it--does that really seem like a lot of work? On top of that, of course, the interface gives you the ability to implement the interface from a new hierarchy which wouldn't work with an abstract base class. –  Bill K Dec 20 '11 at 21:11
add comment

As I commented on @deadnix post: Partial implementations are an anti-pattern, despite the fact that template pattern formalizes them.

A clean solution for this wikipedia example of the template pattern:

interface Game {
    void initialize(int playersCount);
    void makePlay(int player);
    boolean done();
    void finished();
    void printWinner();
}
class GameRunner {
    public void playOneGame(int playersCount, Game game) {
        game.initialize(playersCount);
        int j = 0;
        for (int i = 0; !game.finished(); i++)
             game.makePlay(i % playersCount);
        game.printWinner();
    }
} 
class Monopoly implements Game {
     //... implementation
}

This solution is better, because it uses composition instead of inheritance. The template pattern introduces a dependency between the implementation of the Monopoly rules and the implementation of how games are to be run. However these are two entirely different responsibilities and there is no good reason to couple them.

share|improve this answer
    
+1 for presenting this alternative. looks neater! –  Kiran Ravindranathan Jul 22 '11 at 6:23
    
+1. As a side-note: "Partial implementations are an anti-pattern, despite the fact that template pattern formalizes them.". The description on wikipedia defines the pattern cleanly, only the code example is "wrong" (in the sense that it uses inheritance when it's not needed and a simpler alternative exists, as illustrated above). In other words, I don't think the pattern itself is to blame, only the way people tend to implement it. –  Joh Jul 25 '11 at 9:21
add comment

Abstract classes are not interfaces. They're classes that can't be instantiated.

You need a fully abstract class? Create an interface instead. You need an abstract class with some implementation in it? Create an interface, create a class. Inherit the class, implement the interface. An additional benefit is that some classes may not need the parent class, but will just implement the interface.

But then you would have a non-abstract useless class. Abstract methods are required to fill in functionality hole in the base class.

For example, given this class

public abstract class Frobber {
    public abstract void Frob();

    public abstract boolean IsFrobbingNeeded { get; }

    public void FrobUntilFinished() {
        while (IsFrobbingNeeded) {
            Frob();
        }
    }
}

How would you implement this base functionality in a class that has neither Frob() nor IsFrobbingNeeded?

share|improve this answer
    
An interface can't be instantiated either. –  Sjoerd Jul 21 '11 at 17:22
    
@Sjoerd: But you need a base class with the shared implementation; that can't be an interface. –  configurator Jul 21 '11 at 17:58
add comment

No. Even your proposed alternative includes the use of abstract classes. In addition, since you didn't specify the language, then I'm going to go right ahead and say that generic code is the better option than brittle inheritance anyway. Abstract classes have significant advantages over interfaces.

share|improve this answer
    
-1. I don't understand what "generic code vs inheritance" has to do with the question. You should illustrate or justify why "abstract classes have significant advantages over interfaces". –  Joh Jul 25 '11 at 9:25
add comment

I am a creator of servlet framework where abstract classes play essential role. I would say more, I need semi abstract methods, when a method needs to be overridden in 50% cases and I would like to see warning from compiler about that method wasn't overridden. I resolve the problem adding annotations. Returning back to your question, there are two different use case of abstract classes and interfaces, and no one is obsolete so far.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.