tags:

views:

894

answers:

7

An interface is a 100% abstract class, so we can use an interface for efficient programming. Is there any situation where an abstract class is better than an interface?

+16  A: 

Abstract classes are used when you do intend to create a concrete class, but want to make sure that there is some common state in all the subclasses or a possible common implementation for some operations.

Interfaces cannot contain either.

Uri
I would continue to define the interface, even if defining an abstract class. It makes your code more test friendly and less coupled to a particular implementation.
tvanfosson
Yes, of course, I agree a 100%. In my code, I typically factor out the interface to the interface (that sounded silly), and use the abstract class as a base for the standard implementation and state.
Uri
You said: "and use the abstract class as a base for the standard implementation and stateYou probably meant: "and use the abstract class as a base for the "common implementation" and state"
Shaw
@Shwa: My bad. I should pay more attention to my comments.
Uri
I would only add to take care to, even with a common implementation, always write to the constraints of the interface. I do see a lot of code that, even declaring a variable as of the interface type, make assumptions based on the work of the abstract class.
Renato Soffiatto
I agree. Though in my study of documentation I found that this often ends up obfuscating the view that clients have of the documentation - They care about using the object (which could be a different subtype), and instead they have to read through instructions to overriders they don't care about.
Uri
A: 

Abstract classes are also frequently used in some very useful design patterns such as Template Method

Matt Campbell
+4  A: 

Abstract class v/s interface is one topic that generates lot of curiosity/interest/confusion for anyone new to Java and wants to dig deeper.

This article provides a detailed explanation on the topic. link text

Omnipotent
The link you provided was very useful.It gave clear use of both abstract and interface.
Warrior
+5  A: 

Yes, there is a place for both abstract classes and interfaces.

Let's go with a concrete example. We'll look into how to make a CheckingAccount and SavingsAccount from an abstract AbstractBankAccount and see how we can use an interface differentiate the two types of accounts.

To start off, here's an abstract class AbstractBankAccount:

abstract class AbstractBankAccount
{
    int balance;
    public abstract void deposit(int amount);
    public abstract void withdraw(int amount);
}

We have the account balance as balance and two methods deposit and withdraw that must be implemented by the subclasses.

As we can see, an abstract class declares the structure of how bank accounts should be defined. As @Uri mentions in his response, there is a state to this abstract class, which is the balance field. This would not be possible with an interface.

Now, let's subclass AbstractBankAccount to make a CheckingAccount

class CheckingAccount extends AbstractBankAccount
{
    public void deposit(int amount)
    {
     balance += amount;
    }

    public void withdraw(int amount)
    {
     balance -= amount;
    }
}

In this subclass CheckingAccount, we implemented the two abstract classes -- nothing too interesting here.

Now, how could we implement SavingsAccount? It is different from a CheckingAccount in that it will gain interest. The interest could be increased by using the deposit method, but then again, it's not as if the customer is depositing the interest him/herself. Therefore, it might be more clearer if we had another means of adding money into an account, specifically for interest, say, an accrueInterest method.

We could directly implement the method in SavingsAccount, but we may have more bank account types that can accrue interest in the future, so we may want to make an InterestBearing interface that has the accrueInterest method:

interface InterestBearing
{
    public void accrueInterest(int amount);
}

So, we now can make an SavingsAccount class that can gain interest by implementing the InterestBearing interface:

class SavingsAccount extends AbstractBankAccount implements InterestBearing
{
    public void deposit(int amount)
    {
     balance += amount;
    }

    public void withdraw(int amount)
    {
     balance -= amount;
    }

    public void accrueInterest(int amount)
    {
     balance += amount;
    }
}

Now, if we want to make another type of account, say a PremiumSavingsAccount, we can make a subclass of the AbstractBankAccount and implement the InterestBearing interface to make another interest-bearing account.

The InterestBearing interface can be seen as adding a common feature to different classes. It would have not have made sense to have a feature to deal with interest in a checking account when it doesn't accrue any interest.

So, there are indeed places for both abstract classes and interfaces to coexist and work together in one situation.

coobird
A: 

One more:

There is an article on Java world that describes using interface and abstract classes together:

Check this article on Java World

Shaw
A: 

In general, interfaces describe the public API that your code should use, whereas abstract base classes are best kept as an implementation detail, where common code or state can be kept, to reduce duplication in any implementing classes.

By using interfaces in your API, it becomes easier for people (including you) to write test code against your classes, since you can use test classes that, for example, don't depend on any external resources, or which exhibit explicit kinds of bad-but-difficult-to-simulate-in-real-life behaviour.

So java provides the List interface, and the AbstractList abstract base class to "minimize the effort needed to implement" the interface...

Bill Michell
+2  A: 

There a couple of reasons why you might prefer an implementation-free abstract class over an interface:

  • Certain impossible casts and instanceof operations can be caught at compile time.
  • You do have the option of adding concrete methods in a later version.
  • There used to be a significant performance benefit many years ago.
  • From a highly obscure security perspective, you can't get a pre-existing class to implement the methods by creating a subclass of the pre-existing class and the abstract class.

But on the other hand, the interface Java keyword allows cleaner source.

Tom Hawtin - tackline
Thanks pal.You gave me valuable ideas over my query.
Warrior