0

Where should I use interface as variable type? I see a lot of people say it's best practice to do so, but every example refers to collections:

List<String> list = new ArrayList<>()

Does this practice apply mostly to collections? I never saw anyone use interface when declaring i/o streams for example.

Wade
  • 21
  • 1
  • 2
  • 7

5 Answers5

2

The idea is that you want to hide the actual implementation if it isn't important. This typically makes the code simpler and avoids accidentially using a implementation specific feature.

So therefore only use ArrayList with a new. Use List everywhere else. (Unless you have good reason to)

Note: For Java 10 you can use the var syntax for local variables:

var list = new ArrayList<String>();
Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
0

Using interfaces is better than concrete classes because it is easier if you want to switch the implementation. But this is only applicable if you have a gain of doing that; using List instead of ArrayList in a method of 5 lines does not change much in your code. The advantage is more when you receive them as reference to a method or a constructor because you use the interface/contract and the "user" of your code (that may be you) can easily pass another implementation to improve the program or as mock in a test.

For I/O it is quite common to work with InputStream and OutpuStream, the concrete type is at the discretion of the user. So that you may use an InputStream to read either from the network or a local file.

gervais.b
  • 2,294
  • 2
  • 22
  • 46
0

It is a best practice to refere to the interface because in this way you can always change the actual implementation with no modification on the caller of that interface. Suppose you have a CDI environment like Spring. You can have your ServiceInterface with multiple implementations, but a controller will never see the actual implementation.

Controller:

@Controller
public class MyController {

    @Autowired
    private ServiceInterface service;

    /*stuff*/
}

ServiceInterface:

public interface ServiceInterface{ /*stuff*/ }

Implementation "A":

@Service
@Profile("A")
@Primary
public class ServiceImplementationA implements ServiceInterface {
     /*stuff*/
}

Implementation "B":

@Service
@Profile("B")
public class ServiceImplementationB implements ServiceInterface {
    /*stuff*/
}

Spring has its own mechanism for selecting implementations (which are called profiles), but alternatives exists like factories. As long the interface does not change, you can switch between the two service implementation: no variation will be detected by controller class.

Lorelorelore
  • 3,335
  • 8
  • 29
  • 40
0

It is kind of longsightedness. Yes, there is a rule that,

Always code to interface.

But why?

You use new ArrayList<>() for definition type and List<String> for declarative type. It's good practice. Now let's think, typically for the nonce performance of ArrayList is really suitable for your data and program. What if there exist new container type e.g. called as NicePerformedList which implements List interface as well and makes your program performance much better after 5 years, will you refactor all declarative types in lieu of merely changing definition type?

0

When there are different implementation of methods between different classes , it is a best practice to have an interface with the signature of this methods and implement them in classes. So regardless of which implementation is used we can use the interface as a variable or pass this to other methods as internal variable.

interface MathInterface{

int sum();


}  

class A implements MathInterface
{
@Override
int sum()
{

//implementation
}

}
class B implements MathInterface
{
@Override
int sum()
{

//implementation
}

}

class Main
{

MathInterface mathInterface=new B();

doSomeThing(mathInterface);


} 
helenDeveloper
  • 624
  • 3
  • 8
  • 15