Understanding Java Interfaces
Concept explanation of interfaces as contracts that classes implement
java (1.0+)
2025-11-03
interfaces
oop
polymorphism
concepts
Description
Interfaces in Java define a contract that implementing classes must follow. They specify what methods a class must provide without dictating how they’re implemented. Interfaces enable polymorphism and help achieve loose coupling in design.
Key Concepts
What is an Interface?
- A reference type that contains only constants, method signatures, default methods, static methods, and nested types
- Cannot be instantiated directly
- Defines a contract that implementing classes must fulfill
- Supports multiple inheritance (a class can implement multiple interfaces)
Interface Evolution
- Java 7 and earlier: Only abstract methods and constants
- Java 8: Added default methods and static methods
- Java 9: Added private methods
- Java 16: Added sealed interfaces (preview)
Types of Methods
- Abstract methods: Must be implemented by classes (implicitly public abstract)
- Default methods: Provide default implementation (can be overridden)
- Static methods: Called directly on interface (cannot be overridden)
- Private methods: Helper methods (Java 9+)
Interface vs Abstract Class
- Interfaces: Multiple inheritance, no instance variables, all methods public
- Abstract classes: Single inheritance, can have instance variables, various access modifiers
- Use interfaces for “can-do” relationships
- Use abstract classes for “is-a” relationships with shared implementation
Functional Interfaces
- Interface with exactly one abstract method
- Can be implemented using lambda expressions
- Examples: Runnable, Comparator, Function, Predicate
- Marked with @FunctionalInterface annotation
Benefits
- Polymorphism: Treat different implementations uniformly
- Loose coupling: Depend on abstractions, not concrete classes
- Multiple inheritance: Implement multiple interfaces
- Contract enforcement: Guarantee certain methods exist
- API design: Define clear boundaries between modules
Best Practices
- Keep interfaces focused (Interface Segregation Principle)
- Use descriptive names ending in -able or -er when appropriate
- Prefer composition over inheritance
- Use default methods for backward compatibility
- Document interface contracts clearly
Common Patterns
- Strategy pattern: Multiple implementations of an algorithm
- Dependency injection: Program to interfaces
- Adapter pattern: Implement interface to adapt incompatible classes
- Marker interfaces: Empty interfaces for type identification
Code
// Basic interfaceinterface Drawable { void draw(); // Implicitly public abstract // Default method (Java 8+) default void resize() { System.out.println("Resizing..."); } // Static method (Java 8+) static void printInfo() { System.out.println("This is a Drawable interface"); }}// Implementing interfaceclass Circle implements Drawable { @Override public void draw() { System.out.println("Drawing a circle"); }}class Rectangle implements Drawable { @Override public void draw() { System.out.println("Drawing a rectangle"); } // Override default method (optional) @Override public void resize() { System.out.println("Resizing rectangle specifically"); }}// Multiple interfacesinterface Flyable { void fly();}interface Swimmable { void swim();}class Duck implements Drawable, Flyable, Swimmable { @Override public void draw() { System.out.println("Drawing a duck"); } @Override public void fly() { System.out.println("Duck is flying"); } @Override public void swim() { System.out.println("Duck is swimming"); }}// Functional interface@FunctionalInterfaceinterface Calculator { int calculate(int a, int b); // Can have default methods default void print(int result) { System.out.println("Result: " + result); }}// UsageDrawable circle = new Circle();circle.draw();circle.resize(); // Uses default implementationDrawable.printInfo(); // Static method call// PolymorphismDrawable[] shapes = {new Circle(), new Rectangle()};for (Drawable shape : shapes) { shape.draw();}// Functional interface with lambdaCalculator add = (a, b) -> a + b;Calculator multiply = (a, b) -> a * b;int sum = add.calculate(5, 3);int product = multiply.calculate(5, 3);
Comments
No comments yet. Be the first to comment!
Please login to leave a comment.