Java • Object-Oriented Programming

Defining & Implementing Interfaces — Define and implement an interface

Learn how interfaces create contracts that guarantee classes share common behavior in Java.

Java programming emblem with a coffee cup, code braces, and terminal
Inside this lesson 10 sections 5 questions 7 figures

SECTION 1

Historical Context & Motivation

Before Java existed, programmers working in languages like C and C++ struggled with a fundamental problem: how do you guarantee that unrelated classes share the same set of behaviors without forcing them into the same inheritance tree? C++ offered multiple inheritance, which allowed a class to extend more than one parent. While powerful, multiple inheritance introduced confusing bugs—most famously the diamond problem, where a class could inherit conflicting versions of the same method from two different parents.

When James Gosling and his team at Sun Microsystems designed Java in the early 1990s, they wanted a cleaner solution. They borrowed the concept of interfaces from languages like Objective-C's protocols. An interface defines what a class must do without specifying how it does it. This elegant idea became one of Java's most important features.

1979 • C++ Introduces Multiple Inheritance

Bjarne Stroustrup begins developing C++ with support for multiple inheritance—a powerful but error-prone mechanism for sharing behavior across class hierarchies.

1984 • Objective-C Protocols Emerge

Brad Cox introduces protocols in Objective-C, establishing the idea of a behavioral contract that a class can promise to fulfill without inheriting implementation code.

1995 • Java 1.0 Launches with Interfaces

Java's first release includes interfaces as a core language feature, replacing multiple inheritance with a safer, cleaner abstraction for defining shared contracts.

2014 • Java 8 Adds Default Methods

Java 8 enhances interfaces by allowing default method implementations, enabling interfaces to evolve without breaking existing classes that implement them.

The central question that interfaces answer is this: how can you write code that works with any object that has certain capabilities—like being sortable, drawable, or serializable—without caring about the object's specific class? This is the power of programming to a contract rather than to a specific implementation.

SECTION 2

Core Principles & Definitions

An interface in Java is a reference type—similar to a class—that contains only abstract method signatures, constants, default methods, and static methods. Think of it as a contract or promise: any class that implements the interface must provide concrete code for every abstract method declared in that interface. If a class claims it implements an interface but fails to define even one required method, the compiler will refuse to build the program.

1

Interface = Contract

An interface declares method signatures (name, parameters, return type) but provides no body for those methods. It says what must exist, not how it works.
2

implements Keyword

A class uses the implements keyword to sign the contract. The class must then provide method bodies for every abstract method in the interface.
3

Multiple Interfaces

Unlike class inheritance (single parent only), a class can implement multiple interfaces, gaining several contracts at once without the diamond problem.
4

Polymorphism

An interface type can be used as a variable type. Any object whose class implements that interface can be assigned to that variable, enabling flexible, interchangeable code.
5

Fields Are Constants

Any variable declared in an interface is automatically public static final. Interfaces define behavior, not mutable state.
✦

KEY TAKEAWAY

Think of an interface like a job listing. The listing says "must be able to cook, clean, and manage inventory" but doesn't tell you how to do those things. Any person (class) who applies (implements) must prove they can do all three. Different people will cook and clean in their own style, but the employer (the rest of your program) knows they can rely on those abilities.

SECTION 3

Visual Explanation

«INTERFACE»Drawable+ draw(): voidCircle- radius: double+ draw(): void+ getArea(): doubleimplements DrawableSquare- side: double+ draw(): void+ getPerimeter(): doubleimplements DrawableTriangle- base: double+ draw(): void+ getHeight(): doubleimplements Drawable
The dashed-border box at the top represents the Drawable interface with its single abstract method draw(). The three solid boxes below—Circle, Square, and Triangle—each implement the interface, providing their own version of draw(). Dashed arrows point upward to indicate the "implements" relationship.

In the diagram above, notice that the interface box uses a dashed border to distinguish it from concrete classes, which have solid borders. This is standard UML notation. Each class has its own fields (like radius for Circle), but all three classes share the draw() method because the interface requires it. The beauty of this design is that the rest of your program can work with any Drawable object without knowing whether it's a Circle, Square, or Triangle.

SECTION 4

How Interfaces Work in Code

Step 1: Declaring an Interface

You declare an interface using the interface keyword. Inside the curly braces, you list method signatures—no method bodies. By default, every method in an interface is public and abstract, so you don't need to write those modifiers explicitly (though you can if you want clarity). Here is a basic syntax pattern:

INTERFACE DECLARATION SYNTAX

publicinterfaceInterfaceNamereturnTypemethodName(parameters);public interface InterfaceName { returnType methodName(parameters); }

The interface keyword replaces class. Methods have no curly braces—just a semicolon after the signature. Every method is implicitly public abstract.

Step 2: Implementing the Interface

A class signs the interface contract by using the implements keyword after the class name. The class must then provide a full method body for every abstract method in the interface. If you forget even one method, the Java compiler will produce an error.

IMPLEMENTATION SYNTAX

publicclassClassNameimplementsInterfaceName@OverridepublicreturnTypemethodName(parameters)//yourimplementationherepublic class ClassName implements InterfaceName { @Override public returnType methodName(parameters) { // your implementation here } }

The @Override annotation is optional but strongly recommended—it tells the compiler you intend to fulfill a contract, helping catch typos in method names.

Step 3: Using Interface Types

One of the most powerful features is that you can declare variables using the interface type rather than the class type. For example, Drawable shape = new Circle(5.0); is perfectly valid. The variable shape can hold any object whose class implements Drawable. When you call shape.draw(), Java uses dynamic dispatch to call the correct version of draw() based on the actual object's class at runtime.

How Interface Polymorphism Works at RuntimeDrawable shape = new Circle(5.0);shape.draw(); // Which draw() runs?1. Compile Time2. Runtime Lookup3. ExecuteCOMPILER CHECKS:"Does Drawable havea draw() method?" ✓JVM ASKS:"What is the actual typeof this object?" → CircleJVM RUNS:Circle's version ofdraw() executes ✓Key InsightThe variable type (Drawable) controls what methods you CAN call.The object type (Circle) controls what code ACTUALLY runs.
This diagram traces the three stages of an interface method call: the compiler verifies the method exists in the interface, the JVM identifies the actual object type at runtime, and the correct class-specific implementation executes.

SECTION 5

Interface Syntax & Rules in Detail

Now that you understand the big picture, let's look more closely at the specific rules that govern interfaces in Java. These rules are enforced by the compiler, so violating any of them will prevent your program from compiling.

RuleWhat It MeansCode Example
Cannot be instantiatedYou cannot write new Drawable(). Interfaces have no constructors.// Drawable d = new Drawable(); ← ERROR
Methods are implicitly public abstractYou don't need to write public abstract before each method.void draw(); // same as public abstract void draw();
Fields are implicitly public static finalAll variables in an interface are constants and must be initialized.int MAX_SIZE = 100; // constant
A class can implement multiple interfacesSeparate interface names with commas after the implements keyword.class Dog implements Drawable, Comparable<Dog>
An interface can extend another interfaceUse extends (not implements) between interfaces.interface Resizable extends Drawable { ... }
Implementing class must override ALL abstract methodsUnless the implementing class is itself declared abstract.// Missing method body → compile error

Key rules governing Java interfaces

⚠

Common Mistake

When implementing an interface method, you must declare it public in the class. The interface declares it as implicitly public, and Java does not allow you to reduce the visibility of an overridden method. Writing void draw() without public in your class gives it package-private access, which is more restrictive than public—and the compiler will reject it.

SECTION 6

Worked Example: Building a Shape System

Let's build a complete example from scratch. We will define a Shape interface, create two classes that implement it, and then use polymorphism to process a collection of shapes.

Defining and Implementing the Shape Interface

  1. 1

    Step 1 — Define the Interface

    We create an interface called Shape with two abstract methods: getArea() and getPerimeter(). This contract says that any class implementing Shape must be able to calculate both its area and perimeter.
    public interface Shape { double getArea(); double getPerimeter(); }
  2. 2

    Step 2 — Implement Shape with Circle

    The Circle class implements Shape. It stores a radius field and provides concrete method bodies for both getArea() (π × r²) and getPerimeter() (2 × π × r).
    public class Circle implements Shape { private double radius; public Circle(double radius) { this.radius = radius; } @Override public double getArea() { return Math.PI * radius * radius; } @Override public double getPerimeter() { return 2 * Math.PI * radius; } }
  3. 3

    Step 3 — Implement Shape with Rectangle

    The Rectangle class also implements Shape. It has width and height fields. Its formulas differ from Circle's, but the method signatures match the interface contract exactly.
    public class Rectangle implements Shape { private double width, height; public Rectangle(double width, double height) { this.width = width; this.height = height; } @Override public double getArea() { return width * height; } @Override public double getPerimeter() { return 2 * (width + height); } }
  4. 4

    Step 4 — Use Polymorphism in main()

    In the main method, we create an array of type Shape[]. We can store both Circle and Rectangle objects in this array because they both implement Shape. We then loop through and call getArea() on each—Java automatically calls the correct version.
    public class Main { public static void main(String[] args) { Shape[] shapes = { new Circle(5.0), new Rectangle(4.0, 6.0) }; for (Shape s : shapes) { System.out.println("Area: " + s.getArea()); } } }
  5. 5

    Step 5 — Verify Output

    Running the program produces two lines. The Circle's area is π × 5² ≈ 78.54 and the Rectangle's area is 4 × 6 = 24.0. Java used dynamic dispatch to pick the right getArea() for each object.
    Area: 78.53981633974483 Area: 24.0

SECTION 7

Interfaces vs. Abstract Classes

Students often confuse interfaces with abstract classes because both can declare abstract methods. However, they serve different purposes and follow different rules. The table below highlights the key differences.

FeatureInterfaceAbstract Class
MethodsAll methods are abstract by default (except default/static methods since Java 8)Can have both abstract and fully implemented methods
FieldsOnly constants (public static final)Can have instance variables of any type and visibility
ConstructorsNo constructors allowedCan have constructors (called by subclass constructors)
Multiple inheritanceA class can implement many interfacesA class can extend only one abstract class
When to useWhen unrelated classes need to share a behavior contractWhen related classes share common code that you want to reuse

Interface vs. Abstract Class comparison

✦

KEY TAKEAWAY

Think of an abstract class like a partially assembled IKEA table—some pieces are already put together, but you finish the rest. An interface is more like a blueprint that says "must have four legs and a flat surface" without giving you any pre-built parts. Use an interface when you want unrelated classes to share capabilities; use an abstract class when you want related classes to share code.

SECTION 8

Connection to Advanced Interface Features

The basic interface you've learned today is the foundation, but Java has evolved interfaces significantly since version 8. Understanding what's ahead will help you appreciate why interfaces are designed the way they are.

FeatureWhat You Learned TodayAdvanced Version
Method bodiesInterfaces contain only abstract methods (no bodies)Java 8+ allows default methods with full bodies inside interfaces
Static methodsNot covered in basic interfacesJava 8+ interfaces can contain static utility methods
Functional interfacesInterfaces with multiple methodsAn interface with exactly one abstract method can be used with lambda expressions
Private methodsNot applicableJava 9+ allows private helper methods inside interfaces

Basic vs. Advanced Interface Features

As you progress in Java, you'll encounter interfaces like Comparable, Iterable, and Serializable that are built into the Java standard library. These interfaces power sorting algorithms, for-each loops, and data persistence. Mastering the basics you've learned today gives you the foundation to use and create all of these patterns confidently.

💡

Looking Ahead

In AP Computer Science A, you'll encounter the Comparable<T> interface frequently. It has a single method, compareTo(T other), and implementing it allows your objects to be sorted by Arrays.sort() and Collections.sort() automatically. This is the power of interfaces in action!

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain in your own words why you would use an interface instead of simply adding the same methods to each class independently. What advantage does the interface provide?
Show answer
An interface creates a guaranteed contract that the compiler enforces. Without an interface, two classes might both have a draw() method, but nothing in the language connects them. You couldn't store both objects in a Drawable[] array or pass them to a method that accepts a Drawable parameter. The interface enables polymorphism: you can write a single method that works with any implementing class, and the compiler ensures no class forgets to implement a required method.

Question 2: BASIC CALCULATION

Given the interface public interface Measurable { double getMeasure(); }, write a complete class called BankAccount that implements Measurable. The class should have a balance field, a constructor, and getMeasure() should return the balance.
Show answer
The correct implementation is: public class BankAccount implements Measurable { private double balance; public BankAccount(double balance) { this.balance = balance; } @Override public double getMeasure() { return balance; } }. Note three critical details: (1) the class header uses implements Measurable, (2) getMeasure() is declared public to match the interface's implicit public access, and (3) the @Override annotation is included for safety.

Question 3: INTERMEDIATE

A student writes the following code, but it does not compile. Identify the error and explain how to fix it. public interface Playable { void play(); void pause(); } public class Song implements Playable { public void play() { System.out.println("Playing song"); } }
Show answer
The Song class implements Playable but only provides a body for play(). The pause() method is also required by the interface but is missing from the class. To fix this, the student must add public void pause() { System.out.println("Paused"); } to the Song class. The Java compiler enforces that every abstract method in an interface receives a concrete implementation in the class. Alternatively, the student could declare Song as abstract, but then it could not be instantiated.

Question 4: APPLIED

You are building a notification system for a school app. Define an interface called Notifiable with methods sendNotification(String message) and getRecipient() (returns a String). Then write two implementing classes: EmailNotification and SMSNotification. Finally, write a method broadcastAll(Notifiable[] targets, String msg) that sends the same message to all targets.
Show answer
First, define the interface: public interface Notifiable { void sendNotification(String message); String getRecipient(); }. Then implement EmailNotification with an emailAddress field where sendNotification prints "Emailing [address]: [message]" and getRecipient returns the email. SMSNotification follows the same pattern with a phone number. The broadcastAll method uses a for-each loop: for (Notifiable n : targets) { n.sendNotification(msg); }. This demonstrates polymorphism—the method doesn't know or care whether each target is an email or SMS object.

Question 5: CRITICAL THINKING

Consider a class SmartPhone that implements three interfaces: Camera, Phone, and MusicPlayer. If both Camera and MusicPlayer declare a method void start(), does this cause a compilation error? Explain why or why not, and discuss how you would handle this situation in a real project.
Show answer
No, this does not cause a compilation error. Since both interfaces declare void start() with the same signature and return type, the SmartPhone class provides a single start() implementation that satisfies both contracts simultaneously. Java treats identical abstract method signatures from different interfaces as one requirement. However, this creates a design problem: calling start() should it start the camera or the music player? In a real project, you would reconsider your interface design—perhaps renaming methods to startCamera() and startPlayback() to make the intent clear. If the return types differed (e.g., one returned void, the other returned boolean), the code would indeed fail to compile.

SUMMARY

Lesson Summary

Summary

A Java interface is a reference type that defines a behavioral contract—a set of method signatures that any implementing class must provide. You declare an interface using the interface keyword, and a class adopts the contract using the implements keyword. All methods in an interface are implicitly public and abstract, and all fields are implicitly public static final (constants). Unlike class inheritance, a single class can implement multiple interfaces.

The true power of interfaces lies in polymorphism: you can use an interface type as a variable, parameter, or array type, and any object whose class implements that interface can fill that role. At runtime, Java's dynamic dispatch calls the correct method implementation based on the actual object's class. This allows you to write flexible, reusable code that works with any present or future class that fulfills the contract. Interfaces differ from abstract classes primarily in that they cannot hold instance variables or constructors, and a class can implement many interfaces but extend only one class.

Varsity Tutors • Java • Defining & Implementing Interfaces — Define and implement an interface