Java • Object-Oriented Programming

Multiple Interfaces & Default Methods — Use multiple interfaces and understand default methods (intro)

Learn how a single Java class can implement multiple interfaces and leverage default methods for flexible, modular design.

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

SECTION 1

Historical Context & Motivation

When Java was first released in 1995, its designers made a deliberate choice: a class could only extend one parent class. This restriction, called single inheritance, was meant to avoid the notorious "diamond problem" that plagued languages like C++. However, real-world objects often have multiple roles—a smartphone is both a camera and a phone, for example. Java needed a way to let a class take on multiple roles without the messiness of multiple inheritance.

The solution was interfaces—contracts that define what a class must do, without dictating how. From the very beginning, Java allowed a class to implement multiple interfaces, giving it the flexibility of multiple inheritance without the complexity. But interfaces had a limitation: they could only declare method signatures, never provide actual code. This meant that if you wanted to add a new method to an interface, every class that implemented it had to be updated—an enormous maintenance burden.

1995 • Java 1.0 Released

Java launches with single class inheritance but allows classes to implement multiple interfaces. Interfaces can only contain abstract method declarations.

2004 • Java 5 — Generics & More

Java 5 introduces generics and annotations, making interfaces more powerful. The Comparable and Iterable interfaces become foundational to the Java ecosystem.

2014 • Java 8 — Default Methods Arrive

Java 8 introduces default methods, allowing interfaces to provide method bodies. This enables the new Stream API and lambda expressions without breaking existing code.

2017 • Java 9 — Private Interface Methods

Java 9 allows private methods within interfaces, enabling default methods to share helper logic without exposing it to implementing classes.

The big question that drove the evolution of interfaces was: How can we add new capabilities to interfaces without forcing every existing class to rewrite its code? Default methods in Java 8 answered this question elegantly, and understanding them is essential for writing modern, flexible Java programs.

SECTION 2

Core Principles & Definitions

Before diving into code, let's establish the key ideas behind multiple interfaces and default methods. Think of an interface as a promise or contract. When a class implements an interface, it pledges to provide specific behaviors. A class can sign multiple contracts, taking on multiple roles. A default method is a method defined inside an interface that already includes working code, so classes don't have to override it unless they want to customize the behavior.

1

Interface

A blueprint of method signatures that a class must implement. Declared using the interface keyword. Contains no instance fields (only constants).
2

Multiple Implementation

A single class can implement two or more interfaces using a comma-separated list: class Dog implements Swimmable, Trainable. The class must fulfill all contracts.
3

Abstract Method

A method declared in an interface without a body. The implementing class must provide the actual code. Implicitly public abstract.
4

Default Method

A method in an interface that includes a body, marked with the default keyword. Classes inherit this behavior automatically but may override it.
5

Diamond Problem Resolution

If two interfaces provide the same default method, the implementing class must override it to resolve the ambiguity. Java enforces this at compile time.
✦

KEY TAKEAWAY

Think of interfaces like job certifications. A person can be a certified lifeguard and a certified first-aid responder at the same time—these are two separate "interfaces" they implement. A default method is like a certification that comes with a standard procedure manual: you can follow the manual as-is, or customize your approach as long as you meet the requirements.

SECTION 3

Visual Explanation

The diagram below illustrates how a single class can implement multiple interfaces. Notice that SmartPhone implements three separate interfaces: Camera, Phone, and MusicPlayer. Each interface defines its own set of methods, and the SmartPhone class must provide implementations for all of them. The dashed arrows represent the "implements" relationship.

Multiple Interface Implementation«interface»CameratakePhoto()recordVideo()«interface»PhonemakeCall()sendText()«interface»MusicPlayerplay()pause()default shuffle()classSmartPhoneimplements Camera, Phone, MusicPlayerAll abstract methods must be definedshuffle() inherited from defaultimplementsimplementsimplements
The SmartPhone class implements three interfaces. Dashed arrows indicate the "implements" relationship. Notice that shuffle() in MusicPlayer is a default method (shown in green)—SmartPhone inherits it automatically.

This diagram shows the core idea: multiple interfaces let a single class take on many roles. The SmartPhone is simultaneously a camera, a phone, and a music player. Abstract methods (like takePhoto() and makeCall()) must be implemented by the class. The default method shuffle() already has working code in the interface, so SmartPhone can use it as-is or override it with custom behavior.

SECTION 4

How It Works — Syntax & Rules

Declaring an Interface

An interface is declared with the interface keyword. All methods in an interface are implicitly public and abstract unless they are marked as default or static. Here is the general pattern:

INTERFACE DECLARATION

publicinterfaceInterfaceNamereturnTypemethodName(params);//abstractdefaultreturnTypemethodName(params)//default//bodywithworkingcodepublic interface InterfaceName { returnType methodName(params); // abstract default returnType methodName(params) { // default // body with working code } }

Abstract methods have no body (just a semicolon). Default methods include the default keyword and a full method body in curly braces.

Implementing Multiple Interfaces

A class uses the implements keyword followed by a comma-separated list of interfaces. The class must provide concrete implementations for every abstract method from every interface it implements. If it doesn't, the compiler will throw an error.

MULTIPLE IMPLEMENTATION SYNTAX

publicclassClassNameimplementsInterfaceA,InterfaceB,InterfaceC//MustimplementALLabstractmethodsfromA,B,andCpublic class ClassName implements InterfaceA, InterfaceB, InterfaceC { // Must implement ALL abstract methods from A, B, and C }

A class can also extend one superclass while implementing multiple interfaces: class Dog extends Animal implements Swimmable, Trainable

Default Method Rules

  1. Rule 1 — Class wins: If a class defines the same method as a default method in an interface, the class's version always takes priority.
  2. Rule 2 — Sub-interface wins: If one interface extends another and both provide a default method with the same signature, the more specific (child) interface's version wins.
  3. Rule 3 — Conflict must be resolved: If two unrelated interfaces provide the same default method, the implementing class must override it to resolve the ambiguity.
  4. Rule 4 — Calling a specific default: Use InterfaceName.super.methodName() inside the overriding method to explicitly call one interface's default.

RESOLVING CONFLICTING DEFAULTS

publicclassMyClassimplementsInterfaceA,InterfaceB@Overridepublicvoidgreet()InterfaceA.super.greet();//chooseA′sversionpublic class MyClass implements InterfaceA, InterfaceB { @Override public void greet() { InterfaceA.super.greet(); // choose A's version } }

When two interfaces provide the same default method, you must override it. You can call one interface's version using InterfaceName.super.methodName(), write entirely new logic, or combine both.

SECTION 5

Detailed Breakdown — Interface Method Types

Since Java 8 and Java 9, interfaces can contain several types of methods beyond just abstract declarations. Understanding the differences between these method types is essential for writing clean, modern Java code. The diagram below maps out the full taxonomy of methods you can find inside an interface.

Interface Method Types (Java 9+)Interface MethodsAbstractNo method bodyMust be overriddenImplicitly publicvoid fly();DefaultHas method bodyOptional to overrideUses 'default' keyworddefault void log() {..}StaticHas method bodyCannot be overriddenCalled via interface namestatic int max() {..}Private (Java 9+)Helper for defaultsNot visible to classesReduces code duplicationprivate void helper() {..}used byQuick TipConstants: public static finalfields are also allowed!
A taxonomy of methods available inside Java interfaces (Java 9+). Abstract methods must be overridden, default methods provide optional built-in behavior, static methods belong to the interface itself, and private methods are internal helpers for default methods.
Method TypeKeywordHas Body?Override Required?
Abstract(none — implicit)NoYes
DefaultdefaultYesNo (optional)
StaticstaticYesCannot be overridden
Private (Java 9+)privateYesNot accessible to classes

Comparison of interface method types

SECTION 6

Worked Example — Building a Robot Class

Let's build a complete example step by step. Imagine you're designing a robot for a competition. The robot needs to move, speak, and scan its environment. We'll create three interfaces and one class that implements all of them, with a default method for logging.

Creating a Multi-Interface Robot

  1. 1

    Step 1 — Define the Movable Interface

    We start by defining a Movable interface with an abstract method move() and a default method stop() that provides a standard stopping behavior.
    public interface Movable { void move(int x, int y); default void stop() { System.out.println("Stopping at current position."); } }
  2. 2

    Step 2 — Define the Speakable Interface

    The Speakable interface requires a speak() method. It also provides a default greet() method.
    public interface Speakable { void speak(String message); default void greet() { System.out.println("Hello! I am ready."); } }
  3. 3

    Step 3 — Define the Scannable Interface

    The Scannable interface has one abstract method scan() that returns sensor data as a String.
    public interface Scannable { String scan(); }
  4. 4

    Step 4 — Implement All Three Interfaces

    Our CompetitionRobot class implements all three interfaces. It must provide bodies for move(), speak(), and scan(). It inherits stop() and greet() as defaults without writing any code for them.
    public class CompetitionRobot implements Movable, Speakable, Scannable { @Override public void move(int x, int y) { System.out.println("Moving to (" + x + ", " + y + ")"); } @Override public void speak(String message) { System.out.println("Robot says: " + message); } @Override public String scan() { return "Obstacle detected at 2 meters."; } }
  5. 5

    Step 5 — Test the Robot

    In our main method, we create a CompetitionRobot and call both implemented and default methods.
    CompetitionRobot bot = new CompetitionRobot(); bot.greet(); // Default: "Hello! I am ready." bot.move(5, 10); // "Moving to (5, 10)" bot.speak("Scanning"); // "Robot says: Scanning" System.out.println(bot.scan()); // "Obstacle detected at 2 meters." bot.stop(); // Default: "Stopping at current position."
💡

Notice

The CompetitionRobot only had to write code for three methods, but it gained five capabilities. The two default methods (stop() and greet()) came for free. This is the power of default methods—they reduce boilerplate code while still allowing you to override them if needed.

SECTION 7

Strengths, Limitations & Comparisons

Multiple interfaces and default methods are powerful tools, but like any tool, they come with trade-offs. Understanding when to use them—and when not to—will make you a better Java developer.

FeatureStrengthsLimitations / Pitfalls
Multiple InterfacesEnables a class to take on many roles; promotes flexible, modular design; avoids the complexity of multiple class inheritance.Can lead to a large number of methods a class must implement; if interfaces overlap, conflicts can arise.
Default MethodsAllow interface evolution without breaking existing code; reduce boilerplate; provide sensible fallback behavior.Can create ambiguity if two interfaces define the same default; may tempt developers to put too much logic in interfaces.
Abstract Classes (comparison)Can have instance fields, constructors, and a mix of abstract/concrete methods; good for shared state.Only single inheritance allowed; tighter coupling between parent and child classes.
Diamond Conflict ResolutionJava forces explicit resolution at compile time, preventing runtime surprises.Requires the developer to manually write the override, which can be confusing for beginners.

Strengths and limitations of interfaces vs. abstract classes

⚖️

WHEN TO USE WHICH?

Use interfaces when you want to define capabilities that unrelated classes can share (like Swimmable, Sortable, Printable). Use abstract classes when classes share a common identity and state (like Animal with a name field). Think of it this way: a class is what something IS, while an interface is what something CAN DO.

SECTION 8

Connection to Advanced Concepts

The concepts of multiple interfaces and default methods form the foundation for several advanced Java topics you'll encounter later. Understanding them now gives you a head start on design patterns, functional programming, and API design.

What You Learned TodayWhere It Leads (Advanced)
Multiple interfaces on one classStrategy Pattern and Dependency Injection — using interfaces to swap behavior at runtime
Default methods providing behaviorFunctional interfaces and lambda expressions (Java 8+) — interfaces with exactly one abstract method
Resolving conflicts with InterfaceName.superMixin-style programming — composing behavior from multiple sources, similar to traits in Scala
Interface method types (abstract, default, static)Sealed interfaces (Java 17) — restricting which classes can implement an interface

From introductory to advanced concepts

One particularly important application is functional interfaces. A functional interface has exactly one abstract method, and Java lets you represent it using a lambda expression—a concise way to pass behavior as data. For example, the Comparator interface has one abstract method (compare) and several default methods (thenComparing, reversed). Default methods made this powerful design possible. As you progress in Java, you'll see that interfaces are not just contracts—they are the building blocks of elegant, flexible software architecture.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain the difference between an abstract method and a default method in a Java interface. Why would a developer choose to use a default method instead of making all methods abstract?
Show answer
An abstract method in an interface has no body—just a method signature followed by a semicolon. Every class that implements the interface must provide its own implementation. A default method, on the other hand, includes the default keyword and a full method body, so implementing classes inherit that behavior automatically without writing any code. A developer would choose a default method when they want to add a new capability to an existing interface without forcing every implementing class to update. This is especially useful when maintaining large codebases or libraries where many classes already implement the interface.

Question 2: BASIC CALCULATION

Consider the following code. How many methods must the Eagle class provide implementations for? List them. interface Flyable { void fly(); default void land() { System.out.println("Landing..."); } } interface Huntable { void hunt(String prey); void track(); } class Eagle implements Flyable, Huntable { ... }
Show answer
The Eagle class must implement exactly three methods: fly() from Flyable, and hunt(String prey) and track() from Huntable. The land() method is a default method in Flyable, so Eagle inherits it automatically without needing to provide an implementation. Eagle may optionally override land() if it wants custom landing behavior, but this is not required.

Question 3: INTERMEDIATE

Two interfaces both define a default method with the same signature: interface Printable { default void display() { System.out.println("Printable display"); } } interface Viewable { default void display() { System.out.println("Viewable display"); } } A class Document implements both. What happens if Document does not override display()? Write the code that resolves this conflict by calling Printable's version.
Show answer
If Document does not override display(), the code will not compile. Java cannot decide which default to use when two unrelated interfaces define the same method, so it raises a compile-time error. To resolve this, Document must explicitly override the method. To call Printable's version: class Document implements Printable, Viewable { @Override public void display() { Printable.super.display(); } } Alternatively, you could call Viewable.super.display(), combine both, or write entirely new logic.

Question 4: APPLIED

You're building a game with different character types. Design two interfaces—Attackable (with abstract attack() and default battleCry()) and Healable (with abstract heal() and default meditate()). Then write a Paladin class that implements both, providing custom implementations for the abstract methods and overriding battleCry().
Show answer
interface Attackable { void attack(); default void battleCry() { System.out.println("Charge!"); } } interface Healable { void heal(); default void meditate() { System.out.println("Restoring energy..."); } } class Paladin implements Attackable, Healable { @Override public void attack() { System.out.println("Paladin strikes with holy sword!"); } @Override public void heal() { System.out.println("Paladin heals for 50 HP."); } @Override public void battleCry() { System.out.println("For honor and glory!"); } // meditate() is inherited as default } The Paladin must implement attack() and heal() (abstract), overrides battleCry() with a custom version, and inherits meditate() from Healable without changes.

Question 5: CRITICAL THINKING

Some developers argue that default methods blur the line between interfaces and abstract classes, potentially violating the principle that interfaces should only define "what" a class does, not "how." Do you agree or disagree? Present arguments for both sides and explain a scenario where default methods clearly improve code quality.
Show answer
Arguments for the concern: Traditionally, interfaces represented pure contracts—no behavior, just specifications. Default methods add concrete behavior, making interfaces more like abstract classes. This could lead to "fat interfaces" that mix contract definition with implementation, making the codebase harder to reason about. A class implementing multiple interfaces with default methods might inherit behavior it doesn't expect. Arguments in favor of default methods: They solve a real maintenance problem. Before Java 8, adding a method to an interface (like adding stream() to the Collection interface) would break every class that implemented it. Default methods allow interface evolution without breaking backward compatibility. They also reduce code duplication by providing common logic once instead of requiring every implementor to copy-paste it. A clear improvement scenario: The Java Collections framework added the forEach() default method to Iterable. Without default methods, hundreds of existing collection classes would have needed updates. The default method provided sensible behavior while allowing classes to override it for optimization. This is a case where default methods clearly enhanced the language without sacrificing clean design.

SUMMARY

Lesson Summary

Summary

In this lesson, you learned that Java classes can implement multiple interfaces using a comma-separated list after the implements keyword, enabling a single class to fulfill multiple contracts simultaneously. Every abstract method declared in those interfaces must be implemented by the class, while default methods (introduced in Java 8) provide pre-built behavior that classes inherit automatically. Default methods use the default keyword and include a full method body directly in the interface.

When two interfaces provide conflicting default methods with the same signature, the implementing class must override the method to resolve the ambiguity, optionally using InterfaceName.super.methodName() to select a specific version. Interfaces also support static methods and (from Java 9) private helper methods. Remember the guiding principle: a class defines what something is, while an interface defines what something can do.

Varsity Tutors • Java • Multiple Interfaces & Default Methods