Like abstract classes, interfaces cannot be instantiated directly since they define responsibilities without providing implementations. They are declared using the interface keyword:
// Simple interface definition
public interface Printable {
void print(); // Implicitly public and abstract
}
// Interface with a constant
public interface Taxable {
double TAX_RATE = 0.07; // Implicitly public, static, and final
double calculateTax(); // Calculate tax for this item
}
Note that interface methods are implicitly public and abstract, and any fields are implicitly public, static, and final (constants). This means interfaces cannot store per-instance state.
Like abstract classes, interfaces cannot be instantiated directly. This makes sense since they contain no implementation for their methods (except for default methods).
// A class implementing multiple interfaces
public class Invoice implements Printable, Taxable {
private String customer;
private double amount;
// Constructor and other methods omitted for brevity
@Override
public void print() {
System.out.println("Invoice for: " + customer);
System.out.println("Amount: $" + amount);
System.out.println("Tax: $" + calculateTax());
}
@Override
public double calculateTax() {
return amount * TAX_RATE;
}
}
Note9.3.2.Modern Java Feature: Default Methods.
Since Java 8, interfaces can include default methods. Default methods are methods with implementations. They were introduced primarily to enable interface evolution without breaking existing code. Before Java 8, adding a new method to an interface would break all existing implementations.
public interface Sortable {
// Abstract method (no implementation)
void sort();
// Default method (with implementation)
default void sortDescending() {
System.out.println("Default implementation - using sort() in reverse");
sort(); // Note: calls the abstract method that implementers must provide
// Reverse the order...
}
}
Even with default methods, interfaces still cannot contain instance fields. Default methods should generally be used for:
Caution: Default methods should not be used to implement significant shared logic. That’s what abstract classes are for. Default methods were primarily introduced to allow interfaces to evolve over time without breaking existing code. Overusing them can lead to: