Instantiate interface - What's the use? [duplicate]

11

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

Example:

@Autowired
ThingRepository rep;

ThingRepository is an interface that has a ThingRepositoryImpl class corresponding to the implementation of the interface.

Does anyone know what the purpose of this practice is?

    
asked by anonymous 16.08.2016 / 02:39

2 answers

8

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 to another conversation). The closest you can get to "instantiating an interface" in Java is to instantiate an anonymous class that implements a interface as per 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 application design more flexible. ThingRepository is used as reference type for the same reason that 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 implements persistence using the MySQL database. At one time you may want to use MongoDB instead of MySQL (or who knows MySQL for some clients and MongoDB for others). Using the ThingRepository interface as the reference type you are hiding the actual 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 currently depend on that service. This would not be possible if you refer to the ThingRepositoryImpl class directly, in which case you would have to modify the "client" classes.

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

    
16.08.2016 / 21:33
6

Java allows you to instantiate anonymous classes that implement a particular interface. It's as if you say "create a class, no matter its name, as long as you implement the interface I'm reporting on." There you open keys and fill in the method (s) implementing the interface contract.

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 method parameter type is an interface) and you do not want to have the job of creating a new one class in a .java file apart only to instantiate and use at that point. An anonymous class does, because what matters is the implementation, which will probably only be used in that one situation.

    
16.08.2016 / 02:47