I was asked a question, I wanted to get my answer reviewed here.

Q: In which scenario it is more appropriate to extend an abstract class rather than implementing the interface(s)?

A: If we are using template method design pattern.

Am I correct ?

I am sorry if I was not able to state the question clearly.
I know the basic difference between abstract class and interface.

1) use abstract class when the requirement is such that we need to implement the same functionality in every subclass for a specific operation (implement the method) and different functionality for some other operations (only method signatures)

2) use interface if you need to put the signature to be same (and implementation different) so that you can comply with interface implementation

3) we can extend max of one abstract class, but can implement more than one interface

Reiterating the question: Are there any other scenarios, besides those mentioned above, where specifically we require to use abstract class (one is see is template method design pattern is conceptually based on this only)?

Interface vs. Abstract class

Choosing between these two really depends on what you want to do, but luckily for us, Erich Gamma can help us a bit.

As always there is a trade-off, an interface gives you freedom with regard to the base class, an abstract class gives you the freedom to add new methods later. – Erich Gamma

You can’t go and change an Interface without having to change a lot of other things in your code, so the only way to avoid this would be to create a whole new Interface, which might not always be a good thing.

Abstract classes should primarily be used for objects that are closely related. Interfaces are better at providing common functionality for unrelated classes.


Solution 1:

When To Use Interfaces

An interface allows somebody to start from scratch to implement your interface or implement your interface in some other code whose original or primary purpose was quite different from your interface. To them, your interface is only incidental, something that have to add on to the their code to be able to use your package. The disadvantage is every method in the interface must be public. You might not want to expose everything.

When To Use Abstract classes

An abstract class, in contrast, provides more structure. It usually defines some default implementations and provides some tools useful for a full implementation. The catch is, code using it must use your class as the base. That may be highly inconvenient if the other programmers wanting to use your package have already developed their own class hierarchy independently. In Java, a class can inherit from only one base class.

When to Use Both

You can offer the best of both worlds, an interface and an abstract class. Implementors can ignore your abstract class if they choose. The only drawback of doing that is calling methods via their interface name is slightly slower than calling them via their abstract class name.

Solution 2:

reiterating the question: there is any other scenario besides these mentioned above where specifically we require to use abstract class (one is see is template method design pattern is conceptually based on this only)

Yes, if you use JAXB. It does not like interfaces. You should either use abstract classes or work around this limitation with generics.

From a personal blog post:

Interface:

  1. A class can implement multiple interfaces
  2. An interface cannot provide any code at all
  3. An interface can only define public static final constants
  4. An interface cannot define instance variables
  5. Adding a new method has ripple effects on implementing classes (design maintenance)
  6. JAXB cannot deal with interfaces
  7. An interface cannot extends or implement an abstract class
  8. All interface methods are public

In general, interfaces should be used to define contracts (what is to be achieved, not how to achieve it).

Abstract Class:

  1. A class can extend at most one abstract class
  2. An abstract class can contain code
  3. An abstract class can define both static and instance constants (final)
  4. An abstract class can define instance variables
  5. Modification of existing abstract class code has ripple effects on extending classes (implementation maintenance)
  6. Adding a new method to an abstract class has no ripple effect on extending classes
  7. An abstract class can implement an interface
  8. Abstract classes can implement private and protected methods

Abstract classes should be used for (partial) implementation. They can be a mean to restrain the way API contracts should be implemented.

Solution 3:

Interface is used when you have scenario that all classes has same structure but totally have different functionality.

Abstract class is used when you have scenario that all classes has same structure but some same and some different functionality.

Take a look the article : http://shoaibmk.blogspot.com/2011/09/abstract-class-is-class-which-cannot-be.html

Solution 4:

There are a lot of great answers here, but I often find using BOTH interfaces and abstract classes is the best route. Consider this contrived example:

You're a software developer at an investment bank, and need to build a system that places orders into a market. Your interface captures the most general idea of what a trading system does,

1) Trading system places orders
2) Trading system receives acknowledgements

and can be captured in an interface, ITradeSystem

public interface ITradeSystem{

     public void placeOrder(IOrder order);
     public void ackOrder(IOrder order);

}

Now engineers working at the sales desk and along other business lines can start to interface with your system to add order placement functionality to their existing apps. And you haven't even started building yet! This is the power of interfaces.

So you go ahead and build the system for stock traders; they've heard that your system has a feature to find cheap stocks and are very eager to try it out! You capture this behavior in a method called findGoodDeals(), but also realize there's a lot of messy stuff that's involved in connecting to the markets. For example, you have to open a SocketChannel,

public class StockTradeSystem implements ITradeSystem{    

    @Override 
    public void placeOrder(IOrder order);
         getMarket().place(order);

    @Override 
    public void ackOrder(IOrder order);
         System.out.println("Order received" + order);    

    private void connectToMarket();
       SocketChannel sock = Socket.open();
       sock.bind(marketAddress); 
       <LOTS MORE MESSY CODE>
    }

    public void findGoodDeals();
       deals = <apply magic wizardry>
       System.out.println("The best stocks to buy are: " + deals);
    }

The concrete implementations are going to have lots of these messy methods like connectToMarket(), but findGoodDeals() is all the traders actually care about.

Now here's where abstract classes come into play. Your boss informs you that currency traders also want to use your system. And looking at currency markets, you see the plumbing is nearly identical to stock markets. In fact, connectToMarket() can be reused verbatim to connect to foreign exchange markets. However, findGoodDeals() is a much different concept in the currency arena. So before you pass off the codebase to the foreign exchange wiz kid across the ocean, you first refactor into an abstract class, leaving findGoodDeals() unimplmented

public abstract class ABCTradeSystem implements ITradeSystem{    

    public abstract void findGoodDeals();

    @Override 
    public void placeOrder(IOrder order);
         getMarket().place(order);

    @Override 
    public void ackOrder(IOrder order);
         System.out.println("Order received" + order);    

    private void connectToMarket();
       SocketChannel sock = Socket.open();
       sock.bind(marketAddress); 
       <LOTS MORE MESSY CODE>
    }

Your stock trading system implements findGoodDeals() as you've already defined,

public class StockTradeSystem extends ABCTradeSystem{    

    public void findGoodDeals();
       deals = <apply magic wizardry>
       System.out.println("The best stocks to buy are: " + deals);
    }

but now the FX whiz kid can build her system by simply providing an implementation of findGoodDeals() for currencies; she doesn't have to reimplement socket connections or even the interface methods!

public class CurrencyTradeSystem extends ABCTradeSystem{    

    public void findGoodDeals();
       ccys = <Genius stuff to find undervalued currencies>
       System.out.println("The best FX spot rates are: " + ccys);
    }

Programming to an interface is powerful, but similar applications often re-implement methods in nearly identical ways. Using an abstract class avoids reimplmentations, while preserving the power of the interface.

Note: one may wonder why findGreatDeals() isn't part of the interface. Remember, the interface defines the most general components of a trading system. Another engineer may develop a COMPLETELY DIFFERENT trading system, where they don't care about finding good deals. The interface guarantees that the sales desk can interface to their system as well, so it's preferable not to entangle your interface with application concepts like "great deals".

Solution 5:

Which should you use, abstract classes or interfaces?

Consider using abstract classes if any of these statements apply to your use case:

You want to share code among several closely related classes.

You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).

You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the object to which they belong.

Consider using interfaces if any of these statements apply to your use case:

You expect that unrelated classes would implement your interface. For example, the interfaces Comparable and Cloneable are implemented by many unrelated classes.

You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.

You want to take advantage of multiple inheritance of type.

http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html