Master interfaces, functional interfaces, private, static, and default interface methods, and interface evolution for the OCP 21 exam.
Table of Contents
1. Interfaces Basics
An interface defines a contract that implementing classes must follow. It specifies what methods a class must implement without providing the implementation.
1.1 Interface Declaration
// Basic interface interface Drawable {
void draw();
// Abstract method (implicitly public abstract) } // Interface with multiple methods interface Shape {
double area();
double perimeter();
void draw();
} // Interface with constants (implicitly public static final) interface Constants {
int MAX_SIZE = 100;
String DEFAULT_NAME ="Unknown";
}
1.2 Interface Features
- All methods are implicitly
public abstract - All fields are implicitly
public static final - Cannot be instantiated
- Can extend multiple interfaces
- Classes can implement multiple interfaces
2. Implementing Interfaces
Classes implement interfaces using the implements
keyword.
2.1 Single Interface Implementation
interface Drawable {
void draw();
}
class Circle implements Drawable {
@Override public void draw() {
System.out.println("Drawing circle");
}
} Drawable drawable = new Circle();
drawable.draw();
2.2 Multiple Interface Implementation
interface Drawable {
void draw();
}
interface Movable {
void move();
}
class Shape implements Drawable, Movable {
@Override public void draw() {
System.out.println("Drawing");
}
@Override public void move() {
System.out.println("Moving");
}
}
3. Default Methods
Default methods (Java 8+) provide implementation in interfaces. They allow interface evolution without breaking existing implementations.
3.1 Default Method Syntax
interface Drawable {
void draw();
// Abstract method // Default method with implementation default void printInfo() {
System.out.println("This is a drawable object");
}
default void resize(int factor) {
System.out.println("Resizing by factor:" + factor);
}
} class Circle implements Drawable {
@Override public void draw() {
System.out.println("Drawing circle");
} // Can override default method @Override public void printInfo() {
System.out.println("This is a circle");
}
} Circle circle = new Circle();
circle.draw();
//"Drawing circle" circle.printInfo();
//"This is a circle" (overridden) circle.resize(2);
//"Resizing by factor: 2" (uses default)
3.2 Multiple Inheritance with Default Methods
interface A {
default void method() {
System.out.println("A");
}
} interface B {
default void method() {
System.out.println("B");
}
} // Must override to resolve conflict class C implements A, B {
@Override public void method() {
A.super.method();
// Call A's default method B.super.method();
// Call B's default method System.out.println("C");
}
}
4. Static Methods
Static methods in interfaces (Java 8+) provide utility methods that belong to the interface.
interface MathUtils {
static int add(int a, int b) {
return a + b;
}
static double calculateArea(double radius) {
return Math.PI * radius * radius;
}
} // Called via interface name int result = MathUtils.add(5, 3);
double area = MathUtils.calculateArea(5.0);
// Cannot be called via implementing class instance class Calculator implements MathUtils {
}
Calculator calc = new Calculator();
// calc.add(5, 3);
// Compilation error - static methods belong to
interface
5. Private Methods
Private methods in interfaces (Java 9+) allow code reuse within default and static methods.
interface Processor {
default void process(String data) {
validate(data);
transform(data);
save(data);
} // Private instance method (used by default methods) private void validate(String data) {
if (data == null || data.isEmpty()) {
throw new IllegalArgumentException("Invalid data");
}
} // Private static method (used by static methods) private static void transform(String data) {
// Transformation logic }
static void processStatic(String data) {
transform(data);
// Can call private static method }
}
6. Functional Interfaces
A functional interface has exactly one abstract method. It can be implemented using lambda expressions.
6.1 @FunctionalInterface Annotation
// Functional interface @FunctionalInterface interface Calculator {
int calculate(int a, int b);
// Can have default methods default void printResult(int result) {
System.out.println("Result:" + result);
} // Can have static methods static Calculator create() {
return (a, b) -> a + b;
} // Cannot have multiple abstract methods // void anotherMethod();
// Would break functional interface } // Implementation with lambda Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;
System.out.println(add.calculate(5, 3));
// 8 System.out.println(multiply.calculate(5, 3));
// 15
6.2 Functional Interface Rules
- Must have exactly one abstract method
- Can have multiple default and static methods
- Can have methods from Object class (they don't count)
@FunctionalInterfaceannotation is optional but recommended
7. Common Functional Interfaces
Java provides several built-in functional interfaces in java.util.function
package.
| Interface | Method | Description |
|---|---|---|
| Function<T, R> | R apply(T t) | Takes one argument, returns result |
| Predicate<T> | boolean test(T t) | Takes one argument, returns boolean |
| Consumer<T> | void accept(T t) | Takes one argument, returns void |
| Supplier<T> | T get() | Takes no arguments, returns value |
| BiFunction<T, U, R> | R apply(T t, U u) | Takes two arguments, returns result |
import java.util.function.*;
// Function Function<
String, Integer>
length = s -> s.length();
int len = length.apply("Hello");
// 5 // Predicate Predicate<
Integer>
isEven = n -> n % 2 == 0;
boolean result = isEven.test(4);
// true // Consumer Consumer<
String>
printer = s -> System.out.println(s);
printer.accept("Hello");
// Prints"Hello" // Supplier Supplier<
String>
generator = () ->"Hello";
String value = generator.get();
//"Hello" // BiFunction BiFunction<
Integer, Integer, Integer>
add = (a, b) -> a + b;
int sum = add.apply(5, 3);
// 8
8. Interface Evolution
Interfaces can evolve over time without breaking existing implementations using default methods.
// Original interface interface Drawable {
void draw();
} // Later, add new method without breaking existing code interface Drawable {
void draw();
// New method with default implementation default void resize(int factor) {
System.out.println("Default resize:" + factor);
}
} // Existing implementations continue to work class Circle implements Drawable {
@Override public void draw() {
System.out.println("Drawing circle");
} // resize() uses default implementation } // New implementations can override class Rectangle implements Drawable {
@Override public void draw() {
System.out.println("Drawing rectangle");
}
@Override public void resize(int factor) {
System.out.println("Custom resize:" + factor);
}
}
9. Exam Key Points
Critical Concepts for OCP 21 Exam:
- Interface: Defines contract, methods are public abstract by default
- Fields: public static final by default
- Multiple Implementation: Classes can implement multiple interfaces
- Default Methods: Provide implementation in interfaces (Java 8+)
- Default Method Conflict: Must override if multiple interfaces have same default method
- Static Methods: Belong to interface, called via interface name
- Private Methods: Code reuse within interface (Java 9+)
- Functional Interface: Exactly one abstract method
- @FunctionalInterface: Optional annotation, enforces single abstract method
- Lambda Expressions: Can implement functional interfaces
- Function: Takes input, returns output
- Predicate: Takes input, returns boolean
- Consumer: Takes input, returns void
- Supplier: Takes no input, returns value
- Interface Evolution: Default methods allow adding methods without breaking code
- super.method(): Call parent interface's default method
- Interface.super.method(): Call specific interface's default method
- Cannot Instantiate: Interfaces cannot be instantiated directly
0 Comments