Java Interfaces. Unless you’ve been living under an artificial rock, you know interfaces have become a cornerstone of modern software development. From simple examples like the Google algorithm that recommends restaurants to more sophisticated ones like chat bots and voice recognition systems, interfaces have infiltrated every sector of software.
Interfaces allow programs to communicate with each other without worrying about how they’re implemented. Let’s take a look at what Java interfaces are, why we use them, and how we can implement them in our code.
What are Java Interfaces?
An interface is a contract between a piece of code and its clients. Let’s say we have a chat bot that can interact in a basic way with humans. The contract between the chat bot and humans might look something like this: Interfaces are a powerful language feature that allow us to describe this contract in code. Interfaces are similar to abstract classes in that they’re used to define a contract that code can implement. Unlike abstract classes, however, interfaces cannot contain any executable code. They can only contain method signatures.
Why Should We Use Them?
Using interfaces is a great way to achieve loosely coupled software. By defining interfaces, you can allow different systems to communicate with each other. If the systems use interfaces to communicate, the systems can be updated or replaced without affecting the other systems.
Let’s say we have a LocationService that gets the current location of our device. Let’s say we want to add a feature that finds nearby restaurants with user ratings, but we decide not to use Google Maps because we want to switch to a new mapping service. Now, if LocationService uses Google Maps to get the current device location, we will run into issues when we switch over. If, however, we’ve defined a Location interface and LocationService uses that interface to get the device location, we can easily switch to the new mapping service and LocationService will work the same way.
Defining a Java Interface
An interface is defined with the keyword interface followed by a name. The name of the interface is usually the name of the service the interface represents. After the interface name, we write a declaration of the methods the interface will contain. A method declaration in an interface looks the same as a method declaration in a class, but there are a few differences. 1- The access modifier is omitted. Because interfaces can’t contain any executable code, they don’t need an access modifier.
2- The method signature can contain a default (no parameter) implementation. The method signature is similar to a method signature in a class, but it doesn’t have a parent class to inherit from. Therefore, the method signature can contain a default implementation.
Java Interfaces and Inheritance
The biggest difference between interfaces and abstract classes is that they don’t inherit from each other. This is a good thing because the lack of inheritance means that we can’t create an infinite chain of inheritance. Instead, we create a is-a relationship between the interface and classes. Let’s say our LocationService is an interface and it uses Google Maps to get the device location. Our LocationService interface might look like this:
Now, let’s say we have a class that uses the LocationService interface to get the device location. Our DeviceLocation class might look like this: Now, let’s say we want to switch from Google Maps to Waze. If LocationService inherited from GoogleMaps and Waze, we would have to refactor both the LocationService interface and the DeviceLocation class. This would be a lot of work and would require changing a lot of code in our application.
Instead, we can create a new WazeLocation interface and use the is-a relationship to replace GoogleMaps with Waze. We would do this by changing the LocationService interface to look like this: Now, when we use the LocationService interface in our DeviceLocation class, the code that gets the device location doesn’t have to change.
Instantiating Objects from a Java Interface
An interface can’t be instantiated. This is because an interface only describes what it should do, but not how it does it. When we use an interface in our code, we create an implementation of the interface. Java has special syntax for creating implementations. To create an implementation of an interface, we use the implements keyword after the interface name. For example, let’s say we have an interface named DeviceLocation.
Now, let’s say we have a class that uses the DeviceLocation interface to get the device location. Now, we want to add another implementation of the DeviceLocation interface. Let’s say we have another class that uses the DeviceLocation interface to get the device location. We can now use both implementations in our code. Let’s say we want to get the device location using the NewLocationService class.
Advantages of Using Interfaces
1- Loosely Coupled Software: As we discussed earlier, one of the biggest advantages of using interfaces is that they make our software loosely coupled. This means that we can switch out one system for another without having to change the code that uses the system.
2- Easier to Replace Code: Another advantage of using interfaces is that it’s easier to replace code. Let’s say we have a class that uses a hard-coded API key. If the API key ever changes, we have to go through our entire codebase and make the change. If, however, the class uses a function that verifies the API key, we can update the function with the new API key and the rest of our code will continue working the same way.
3- Easier to Test: Using interfaces in our code makes it easier to test. Let’s say we have a class that is dependent on an external service. We can’t test this class because we don’t have access to the external service. Instead, if we create a mock implementation of the external service and use it in our code, we can test the class without having to use the real external service.
When to Use Interfaces
As we discussed earlier, interfaces can’t contain executable code. This means they don’t have any state and they can’t be used to implement any functionality. Interfaces are basically a list of method signatures. That being said, we should use interfaces when we want to decouple our code and provide a contract between our code and its clients.
To Sum Up
When we build software, we want it to be as decoupled as possible. Interfaces are a great way to achieve this. When we use interfaces, we create a contract between different systems in our application. This allows us to switch out one system for another without having to change the code that uses the system. Using interfaces also makes our code easier to test and easier to replace.