1. What is an interface?
If an abstract class is a house blueprint, then an interface is more like an agreement or a “contract” to perform specific tasks. For example, if you call a plumber, you expect that they can “fix the faucet” and “stop the leak.” How they do it doesn’t concern you — the main thing is the result. In Java, an interface is exactly such a contract: it states which methods must be implemented, but not how.
Short and to the point:
An interface is a special type in Java that defines a set of methods that classes subscribing to this interface must implement.
- An interface describes only “what to do”, not “how to do it”.
- Before Java 8, interfaces did not contain method implementations.
- An interface is a pure contract: if a class implements an interface, it must implement all of its methods.
Why is this convenient?
- You can “attach” several interfaces to a class — that is, give it several “roles.”
- It enables building flexible and extensible architectures where classes can implement different capabilities.
- Interfaces are widely used in the Java standard library (for example, Comparable, Serializable, Runnable, etc.).
2. Interface declaration syntax
Declaring an interface in Java is very straightforward. Use the interface keyword. Before Java 8, interface methods were considered public abstract by default, even if not explicitly specified. This means the method must be implemented in the class that implements the interface.
Example of an interface
public interface Movable {
void move(int x, int y);
}
- Here we declared the Movable interface (it can be understood as “capable of moving”).
- Inside, the method move(int x, int y) is declared. There is no method body — only the signature. This is the “contract”: “if you implement Movable — you must implement move.”
Syntax specifics
- Methods in an interface have no body (before Java 8).
- All interface methods are public abstract by default (you can omit them explicitly).
- An interface can contain only constants (public static final), not regular fields.
Example with a constant
public interface Constants {
int MAX_SPEED = 100; // public static final by default
}
3. Difference between an interface and a class
An interface is not a class! Let’s understand the difference.
| Class (including abstract) | Interface |
|---|---|
| Can contain fields (state) | Cannot contain fields (only constants) |
| Can contain method implementations | Before Java 8, interfaces could not contain implementations, only signatures |
| Can be instantiated with new (if not abstract) | Cannot be instantiated directly |
| Only single inheritance (extends) | A class can implement multiple interfaces (implements) |
| Used for “what it is” | Used for “what it can do” |
A class implements an interface using implements
public class Robot implements Movable {
@Override
public void move(int x, int y) {
System.out.println("The robot moves to point (" + x + ", " + y + ")");
}
}
- The Robot class implements the Movable interface.
- The implements keyword means “implements.”
- You must implement all interface methods (otherwise there will be a compilation error).
- Don’t forget the @Override annotation — it’s not mandatory, but it helps the compiler and you avoid mistakes.
4. Example of using an interface
Let’s write a simple example to see how this works in practice. Suppose we have a Movable interface, and we want different classes to “move”: a robot, a car, an animal...
Step 1. Declare the interface
public interface Movable {
void move(int x, int y);
}
Step 2. Implement the interface in a class
public class Robot implements Movable {
@Override
public void move(int x, int y) {
System.out.println("The robot moves to point (" + x + ", " + y + ")");
}
}
Step 3. Use the interface
public class Main {
public static void main(String[] args) {
Movable m = new Robot(); // A variable of the interface type!
m.move(10, 20); // Output: The robot moves to point (10, 20)
}
}
Note
- We can declare a variable of the interface type (Movable m) and assign it an object of a class that implements this interface (new Robot()).
- This allows you to write generic code that works with any “movable” object without knowing what the class actually is.
Compilation error if a method isn’t implemented
Error: Class 'Robot' must either be declared abstract or implement abstract method 'move(int, int)' in 'Movable'
This is the power of interfaces — they guarantee that all implementing classes will have the required methods.
5. Interfaces in the Java standard library
Interfaces are not just a “school” topic. They are used throughout the Java standard library. Here are a few examples:
- Comparable<T> — an interface for comparing objects (e.g., during sorting).
- Runnable — an interface to start a thread.
- Serializable — a marker interface indicating that an object can be serialized.
- List, Set, Map — collection interfaces.
Example: Comparable
public class Person implements Comparable<Person> {
String name;
int age;
// Constructor and other methods...
@Override
public int compareTo(Person other) {
return this.age - other.age;
}
}
Now Person objects can be sorted because they implement the Comparable interface.
6. Visual diagram: how an interface works
+-------------------+ +-------------------+
| interface | | class |
| Movable |<--------| Robot |
|-------------------| |-------------------|
| +move(int, int) | | +move(int, int) |
+-------------------+ +-------------------+
- The arrow shows that the Robot class implements the Movable interface.
- The interface defines only “what must exist”, and the class defines “how it works”.
A real-life analogy
An interface in Java is like a driver’s license. If you have a license (you implement the “Driver” interface), it means you can drive a car. Exactly how you do it is a detail: some people drive carefully, some quickly, but the important thing is that you commit to being able to do it.
7. Practical example: continuing our application
public interface Movable {
void move(int x, int y);
}
public class Animal implements Movable {
protected String name;
public Animal(String name) {
this.name = name;
}
@Override
public void move(int x, int y) {
System.out.println(name + " moves to point (" + x + ", " + y + ")");
}
}
public class Robot implements Movable {
private String model;
public Robot(String model) {
this.model = model;
}
@Override
public void move(int x, int y) {
System.out.println("Robot " + model + " drives to coordinates (" + x + ", " + y + ")");
}
}
public class Main {
public static void main(String[] args) {
Movable[] movables = {
new Animal("Fluffy"),
new Robot("R2D2")
};
for (Movable m : movables) {
m.move(5, 10);
}
}
}
Output:
Fluffy moves to point (5, 10)
Robot R2D2 drives to coordinates (5, 10)
We created an array of objects of type Movable. It can hold any objects that implement this interface! The loop code doesn’t know exactly what it is dealing with — an animal or a robot — but it knows that each of them can move.
8. Common mistakes when working with interfaces
Mistake No. 1: trying to create an interface object directly. An interface is a contract, not a concrete object. You cannot write new Movable() — this will cause a compilation error. You need to create objects of classes that implement the interface.
Mistake No. 2: not all interface methods are implemented. If a class implements an interface but does not implement all of its methods, the compiler will throw an error: “Class must either be declared abstract or implement abstract method ...”. If you don’t want to implement all methods, declare the class as abstract.
Mistake No. 3: forgetting about access modifiers. Interface methods are always public (even if not explicitly written). In the implementing class you cannot reduce the access level, so the method must also be public.
Mistake No. 4: trying to add regular fields to an interface. In an interface you can declare only constants (public static final). You cannot add regular (non-static) fields.
GO TO FULL VERSION