Another way to achieve abstraction in Java is with interfaces.
An interface is a completely "abstract class" that is used to group related methods with empty bodies.
To access the interface methods, the interface must be "implemented" (kinda like inherited) by another class with the implements keyword (instead of extends). The body of the interface method is provided by the "implement" class.
// Interface
interface Animal {
public void animalSound(); // interface method (does not have a body)
public void sleep(); // interface method (does not have a body)
}
// Pig "implements" the Animal interface
class Pig implements Animal {
public void animalSound() {
// The body of animalSound() is provided here
System.out.println("The pig says: wee wee");
}
public void sleep() {
// The body of sleep() is provided here
System.out.println("Zzz");
}
}
class Main {
public static void main(String[] args) {
Pig myPig = new Pig();
myPig.animalSound();
myPig.sleep();
}
}
abstract and public.public, static and final.To implement multiple interfaces, separate them with a comma.
interface FirstInterface {
public void myMethod(); // interface method
}
interface SecondInterface {
public void myOtherMethod(); // interface method
}
class DemoClass implements FirstInterface, SecondInterface {
public void myMethod() {
System.out.println("Some text..");
}
public void myOtherMethod() {
System.out.println("Some other text...");
}
}
Historically, interfaces could only contain abstract methods. However, modern Java has introduced powerful new features to interfaces:
default methods (Java 8): Allow you to add methods with a body to an interface. This is incredibly useful for adding new methods to existing interfaces without breaking the classes that already implement them.static methods (Java 8): Utility methods that belong to the interface itself, not to any implementing object.private methods (Java 9): Used to share common code between multiple default or static methods within the interface itself, keeping the interface clean and encapsulated.
interface Vehicle {
// Abstract method
void start();
// Default method (has a body!)
default void stop() {
System.out.println("Vehicle is stopping...");
logAction("stop");
}
// Static method
static void service() {
System.out.println("Performing standard vehicle service.");
}
// Private method (Java 9+)
private void logAction(String action) {
System.out.println("Log: Vehicle performed action - " + action);
}
}
class Car implements Vehicle {
public void start() {
System.out.println("Car starts with a key.");
}
}
public class Main {
public static void main(String[] args) {
Vehicle.service(); // Call static method directly on the Interface
Car myCar = new Car();
myCar.start();
myCar.stop(); // Uses the default method from the interface
}
}
A common interview question is knowing when to use an Abstract Class versus an Interface.
| Feature | Abstract Class | Interface |
|---|---|---|
| Inheritance | A class can only extends one abstract class. |
A class can implements multiple interfaces. |
| State (Variables) | Can have regular variables (state) that can be modified. | Variables are implicitly public static final (constants). |
| Constructors | Can have constructors. | Cannot have constructors. |
| Use Case | Use when classes share a core "identity" (e.g., Dog is an Animal). |
Use when classes share a "capability" (e.g., Bird and Airplane are Flyable). |
Which keyword is used by a class to implement an interface?