'Why should I use an interface when there is only one implementation class?

I'm new at programming and I'm learning Java. I was just wondering why I should use an interface when there is only one implementation class?



Solution 1:[1]

You do this to prevent others from accessing your implementing type. For example, you could hide your implementing type inside a library, give the type package access, and return an instance of your interface to the users of your library:

// This is what the users of your library know about the class
// that does the work:
public interface SomeInterface {
    void doSomethingUseful();
    void doSomethingElse();
}

// This is the class itself, which is hidden from your clients
class MyImplementation implements SomeInterface {
    private SomeDependency dependency = new SomeDependency();
    public void doSomethingUseful() {
        ...
    }
    public void doSomethingElse() {
        ...
    }
}

Your clients obtain objects like this:

public class MyFactory {
    static SomeInterface make() {
        // MyFactory can see MyImplementation
        return new MyImplementation();
    }
}

This trick becomes useful when the implementation uses lots of libraries. You efficiently decouple the interface of your library from its implementation, so that the user wouldn't have to know about the dependencies internal to your library.

Solution 2:[2]

One reason is to maintain the open/closed principle, which states that your code should be open for extension, but closed for modification. Although you only have one implementing class now, chance is that you will need another differing implementation class with the passing of time. If you extract the implementation into an interface beforehand, you just have to write another implementing class ie. You don't have to modify a perfectly working piece of code, eliminating the risks of introducing bugs.

Solution 3:[3]

To respect the Interface Segregation Principle.

The decision to create an interface should not be based on the number of implementing classes, but rather on the number of different ways that object is used. Each ways the object is used is represented by an interface, defined with the code that uses it. Say your object needs to be stored in memory, in collections that keep objects in order. That same object and also needs to be stored in some persistent storage.

Say you implement persistence first. What is needed by the storage system is a unique identifier for the persisted objects. You create an interface, say Storable, with a method getUniqueId. You then implement the storage.

Then, you implement the collection. You define what the collection needs from stored objects in an interface, like Comparable, with a method compareTo. You can then implement the collection with dependency on Comparable.

The class you want to define would implement both interfaces.

If the class you are defining implement a single interface, that interface would have to represent the needs of the collection and storage system. That would cause, for example:

  • unit tests for the collection would have to be written with objects that implement Storable, adding a level of complexity.

  • if the need arise later to display the object, you would have to add methods needed by the display code to the single interface, and modify the tests for collection and storage to also implement the methods needed for display.

I talk about impact on test code here. The problem is larger if other production level objects need storage and not display. The larger the project, the larger the issue created by not respecting the interface segregation principle will become.

Solution 4:[4]

It can give you the flexibility to add more implementations in the future without changing the client code which references the interface.

Another example of when it can be useful is to simulate multiple inheritance in Java when it is needed. For example, suppose you have an interface MyInterface and an implementation:

public interface MyInterface {
  void aMethod1();
  void aMethod2();
}

class MyInterfaceImpl implements MyInterface {
  public void aMethod1() {...}
  public void aMethod2() {...}
}

You also have an unrelated class with its own hierarchy:

public class SomeClass extends SomeOtherClass {
 ...
}

Now you want to make SomeClass be of type MyInterface but you also want to inherit all the code that is already existing in MyInterfaceImpl. Since you cannot extend both SomeOtherClass and MyInterfaceImpl, you can implement the interface and use delegation:

public class SomeClass extends SomeOtherClass implements MyInterface {
  private MyInterface myInterface = new MyInterfaceImpl();

  public void aMethod1() {
    myInterface.aMethod1();
  }

  public void aMethod2() {
    myInterface.aMethod2();
  }
  ...
}

Solution 5:[5]

I see a lot of good points being made in this post. Also wanted to add my 2 cents to this collection of knowledge.

Interfaces Encourage parallel development in a team environment. There can be 2 classes A and B, with A calling B's API. There can be 2 developers simultaneously working on A and B. while B is not ready, A can totally go about it's own implementation by integrating with B's interfaces.

Interfaces serve as a good ground for establishing API Contracts between different layers of code.

It's good to have a separation of concerns with Interface handling implicit API documentation. it's super easy to refer to one and figure which APIs are accessible for the clients to call.

Lastly, it's better to practice using interfaces as a standard in a project than having to use it on a case by case bases (where you need multiple implementations). This ensures consistency in your project.

For the Art that Java Code is, interfaces make thmem even more beautiful :)

Solution 6:[6]

You shoulnt do anything without thinking and reasoning.

There might be cases where you might want to add an interface even for a single implementation ... but IMO that's an OBSOLETE PRACTICE coming from old EJB times, that people use and enforce without the proper reasoning and reflection.

... and both Martin Fowler, Adan Bien, and others has been saying it for years.

https://martinfowler.com/bliki/InterfaceImplementationPair.html

https://www.adam-bien.com/roller/abien/entry/service_s_new_serviceimpl_why

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Gerald V.
Solution 3 Alain Bienvenue
Solution 4 Dragan Bozanovic
Solution 5 richardec
Solution 6 Rafael