7.5 Interfaces
An interface is a reference type in Java that contains abstract methods, default methods, static methods, and constants. It defines a contract that implementing classes must follow.
Basic Interface Syntax
java
// Interface declaration
interface Drawable {
// Constant (implicitly public, static, final)
String DEFAULT_COLOR = "black";
// Abstract method (implicitly public abstract)
void draw();
// Default method (Java 8+)
default void setColor(String color) {
System.out.println("Setting color to: " + color);
}
// Static method (Java 8+)
static void printInfo() {
System.out.println("This is a Drawable interface");
}
}
Implementing Interfaces
java
class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
}
class Rectangle implements Drawable {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("Drawing a rectangle " + width + "x" + height);
}
}
Multiple Interface Implementation
java
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
// Class implementing multiple interfaces
class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("Duck is flying");
}
@Override
public void swim() {
System.out.println("Duck is swimming");
}
}
Interface Inheritance
java
interface Animal {
void eat();
void sleep();
}
interface Mammal extends Animal {
void giveBirth();
}
class Human implements Mammal {
@Override
public void eat() {
System.out.println("Human is eating");
}
@Override
public void sleep() {
System.out.println("Human is sleeping");
}
@Override
public void giveBirth() {
System.out.println("Human gives birth to live young");
}
}
Functional Interfaces (Java 8+)
java
// Single abstract method interface
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
// Can have default methods
default void printResult(int result) {
System.out.println("Result: " + result);
}
}
// Using lambda expressions
public class FunctionalInterfaceDemo {
public static void main(String[] args) {
Calculator addition = (a, b) -> a + b;
Calculator multiplication = (a, b) -> a * b;
System.out.println("5 + 3 = " + addition.calculate(5, 3));
System.out.println("5 * 3 = " + multiplication.calculate(5, 3));
}
}
Complete Interface Example
java
// Banking system interfaces
interface Account {
void deposit(double amount);
void withdraw(double amount);
double getBalance();
}
interface InterestBearing {
double calculateInterest();
void applyInterest();
}
interface Transferable {
void transfer(Account toAccount, double amount);
}
// Implementing multiple interfaces
class SavingsAccount implements Account, InterestBearing, Transferable {
private double balance;
private double interestRate;
public SavingsAccount(double initialBalance, double interestRate) {
this.balance = initialBalance;
this.interestRate = interestRate;
}
@Override
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("Deposited: $" + amount);
}
}
@Override
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
System.out.println("Withdrawn: $" + amount);
}
}
@Override
public double getBalance() {
return balance;
}
@Override
public double calculateInterest() {
return balance * interestRate;
}
@Override
public void applyInterest() {
double interest = calculateInterest();
balance += interest;
System.out.println("Interest applied: $" + interest);
}
@Override
public void transfer(Account toAccount, double amount) {
if (amount > 0 && amount <= balance) {
this.withdraw(amount);
toAccount.deposit(amount);
System.out.println("Transferred: $" + amount);
}
}
}
Default Methods in Interfaces
java
interface Logger {
void log(String message);
// Default method - provides default implementation
default void logError(String error) {
log("ERROR: " + error);
}
default void logInfo(String info) {
log("INFO: " + info);
}
}
class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("File Log: " + message);
// Actual file logging implementation
}
}
class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println("Console: " + message);
}
// Can override default methods
@Override
public void logError(String error) {
System.out.println("🚨 CRITICAL ERROR: " + error);
}
}
Static Methods in Interfaces
java
interface MathOperations {
static int add(int a, int b) {
return a + b;
}
static int multiply(int a, int b) {
return a * b;
}
static double power(double base, double exponent) {
return Math.pow(base, exponent);
}
}
public class InterfaceStaticMethods {
public static void main(String[] args) {
// Call static methods directly on interface
int sum = MathOperations.add(5, 3);
int product = MathOperations.multiply(5, 3);
System.out.println("Sum: " + sum);
System.out.println("Product: " + product);
}
}
Interface vs Abstract Class
Feature | Interface | Abstract Class |
---|---|---|
Methods | Abstract, default, static | Abstract and concrete |
Fields | Only constants | Any fields |
Inheritance | Multiple | Single |
Constructors | No | Yes |
Access | Public only | Any access modifier |
When to Use Interfaces
- Multiple inheritance of type
- Defining contracts for unrelated classes
- API design and abstraction
- Callback mechanisms and event handling
- Strategy pattern implementation