Instantiating interface - What’s the point?

Asked

Viewed 3,452 times

11

I learned in college and in all the materials I saw that the interface serves to define a pattern that classes should follow and interfaces CANNOT be instantiated. However I came across projects that have an interface and a class q implements this interface. However, when it is instantiated for use, the interface with the @Autowired annotation is instantiated and without new instead of the class that implemented it.

Example:

@Autowired
ThingRepository rep;

being Thingrepository an interface that has a Thingrepositoryimpl class corresponding to the interface implementation.

Does anyone know the purpose of this practice?

  • 5

    Related: http://answall.com/q/138320/27190

  • 1

    @Denercarvalho I would say that it is even duplicate. I do not vote because it would close the question and I would like more opinions.

  • @bigown though I question at the end of my question about the instantiation of the interface, but my question questions other subjects as well.

  • @The important thing to classify as duplicate is that if there is an answer that answers what was asked here, it does not matter if it answered other things together. Duplicate does not mean that the question has to be the same, imposed if it answers. I think so, but I’m not 100% sure about the final vote.

  • @Anthonyaccioly Thank you for the answer. That was exactly my doubt. So at the end of the day he’s using the implementation instead of the interface. Time to use. I couldn’t use "Thingrepositoryimpl rep" instead of "Thingrepository rep", it would make more sense to me.

  • As Anthony Accioly said, Spring is smart enough to find a class that implements the interface and instantiate it.

Show 1 more comment

2 answers

9


The annotation @Autowired is not instantiating an interface.

There is no way to instantiate an interface since the interface is just a "contract" (in Java 8 there are methods default with concrete implementations but this is subject for another conversation). The closest you can come to "instantiating an interface" in Java is instantiating a anonymous class implementing an interface according to Piovezan’s response. But that’s not what Spring is doing in this example.

Spring actually creates an instance of ThingRepositoryImpl‌. Additionally the framework can also wrap the implementation with proxies or do Weaving to provide aspects such as transaction control for the application.

In this example you are using the interface as reference type. The idea is to hide the implementation to make the design of the most flexible application. ThingRepository is used as a reference type for the same reason we usually expose the interface List and not one of its concrete types as ArrayList in the Apis:

List<String> list = buildList();

public List<String> buildList() {
    List<String> list = new ArrayList<>();
    // você pode trocar a implementacao para LinkedList sem  
    // mudanças no restante da aplicação
    return list;
}

Assume that ThingRepositoryImpl today implement persistence using the Mysql database. After a while you may want to use Mongodb instead of Mysql (or maybe use Mysql for some clients and Mongodb for others). Using the interface ThingRepository as a reference type you are hiding the concrete implementation of the service. This way you can always create a new implementation of ThingRepository (e. g., ThingRepositoryMongoDBImpl) and replace it with Spring transparently for the classes that today depend on this service. This would not be possible if you referenced the class ThingRepositoryImpl directly, in that case you would have to modify the classes "clients".

In short, there is a maxim "Program to the interface, not the implementation" that marries well with the service of Dependency injection provided by Spring. Combining both design of its application becomes more flexible (i.e., it becomes easier to evolve the application).

6

Java allows instantiating anonymous classes that implement a certain interface. It’s as if you say "create a class, no matter what its name, as long as you implement the interface I am reporting". Then you open keys and fill in the (s) method(s) that implement the contract of this interface.

MinhaInterface variavel = new MinhaInterface() {
    @Override
    public void meuMetodo() {
        // Uma implementação qualquer
    }
};

The most common utility is when you need to pass an object that implements a particular interface as a parameter to a method (in other words, the type of the method parameter is an interface) and you don’t want to have the trouble of creating a new class in a file .java apart just to do instantiation and use at that point. An anonymous class serves, because what matters is the implementation, which will probably only be used in that single situation.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.