Java + Spring Boot track

Lesson 10 · Part 2: Object-Oriented Programming

Interfaces

An interface is a contract that only determines “what a class can do.” Java classes can only inherit from one parent, but multiple interfaces (implements) can be…

Part 2: Object-Oriented Programming4 min readFree lesson

An interface is a contract that only determines “what a class can do.” Java classes can only inherit from one parent, but multiple interfaces (implements) can be implemented, allowing for free combination of actions.

Learning Objectives

  • Define the contract with the interface keyword
  • Implement the interface with implements
  • Know the meaning of JDK 8+ default method
  • Learn the concept of functional interface (@FunctionalInterface) (see Part 18 for detailed usage)

Key concepts

1) Interface definition

public interface Printable {
    void print();   //public abstract is the default
}
  • All methods default to public abstract
  • All fields are public static final (constant)
  • No need to write separate keywords

2) implements

public class Document implements Printable {
    private String text;
    public Document(String t) { this.text = t; }
    @Override
    public void print() {
        System.out.println(">> " + text);
    }
}

Multiple interfaces can be implemented simultaneously: implements A, B, C.

3) default method

public interface Greeter {
    String name();
    default String greet() {
        return "Hello, " + name();
    }
}

By providing a default implementation, adding methods to an interface does not break the existing implementation class.

4) Functional interface

@FunctionalInterface
interface Calc {
    int apply(int a, int b);
}

An interface with exactly 1 abstract method. It can be briefly implemented with lambda.

Calc add = (a, b) -> a + b;
add.apply(2, 3);   // 5

See as example

Example 1 — Printable.java + Document.java: Interface implementation

Printable.java:

public interface Printable {
    void print();
}

Document.java:

public class Document implements Printable {
    private String text;
    public Document(String t) { this.text = t; }

    @Override
    public void print() {
        System.out.println(">> " + text);
    }

    public static void main(String[] args) {
        Printable p = new Document("Hello, Interface!");
        p.print();
    }
}

Execution result

>> Hello, Interface!

Memo: If you leave the variable type as an interface, it can be replaced with any implementation.

Example 2 — MultipleInterface.java: Implementing multiple interfaces

public class MultipleInterface {
    interface Flyable { void fly(); }
    interface Swimmable { void swim(); }

    static class Duck implements Flyable, Swimmable {
        @Override public void fly() { System.out.println("ducks fly"); }
        @Override public void swim() { System.out.println("duck swimming"); }
    }

    public static void main(String[] args) {
        Duck d = new Duck();
        d.fly();
        d.swim();

        Flyable f = d;
        Swimmable s = d;
        f.fly();
        s.swim();
    }
}

Execution result

ducks fly
duck swimming
ducks fly
duck swimming

Note: The same object can be viewed through different interfaces.

Example 3 — DefaultMethod.java : default method

public class DefaultMethod {
    interface Greeter {
        String name();
        default String greet() { return "Hello, " + name(); }
    }

    static class Korean implements Greeter {
        public String name() { return "exponent"; }
    }
    static class English implements Greeter {
        public String name() { return "John"; }
        @Override
        public String greet() { return "Hi, " + name(); }
    }

    public static void main(String[] args) {
        System.out.println(new Korean().greet());
        System.out.println(new English().greet());
    }
}

Execution result

Hello, Jisoo
Hi, John

Note: The default method can be used as is or overridden by children.

Example 4 — FunctionalDemo.java: Functional interface + lambda

public class FunctionalDemo {
    @FunctionalInterface
    interface Calc {
        int apply(int a, int b);
    }

    public static void main(String[] args) {
        Calc add = (a, b) -> a + b;
        Calc mul = (a, b) -> a * b;
        Calc max = (a, b) -> a > b ? a : b;

        System.out.println("add(2,3)=" + add.apply(2, 3));
        System.out.println("mul(2,3)=" + mul.apply(2, 3));
        System.out.println("max(2,3)=" + max.apply(2, 3));
    }
}

Execution result

add(2,3)=5
mul(2,3)=6
max(2,3)=3

Memo: Lambda is covered in detail in Part 18. Here, just keep in mind the concept of “functional interface = object of lambda”.

Common Mistakes

  1. Confusion between implements and extends (interface is implements)
  2. Interface methods are not implemented → the class becomes an abstract class.
  3. default method conflict (overriding is required when the same signature is present in both interfaces)
  4. Two abstract methods in functional interface (@FunctionalInterface compilation error)
  5. Trying to put an instance field on an interface (not possible)

Cleanup

  • An interface is a contract of “what you can do”
  • Class multiple inheritance
  • The default method is a safety net for interface extensions.
  • Functional interfaces are very powerful when combined with lambdas.

Try it yourself

cd 02_Object-Oriented/10_Interface/src
javac Printable.java Document.java
java Document

Example files

The runnable files used in this lesson. Copy them into your own project and experiment.

src/DefaultMethod.javaJava
public class DefaultMethod {
    interface Greeter {
        String name();
        default String greet() { return "Hello, " + name(); }
    }

    static class Korean implements Greeter {
        public String name() { return "exponent"; }
    }
    static class English implements Greeter {
        public String name() { return "John"; }
        @Override
        public String greet() { return "Hi, " + name(); }
    }

    public static void main(String[] args) {
        System.out.println(new Korean().greet());
        System.out.println(new English().greet());
    }
}
src/Document.javaJava
public class Document implements Printable {
    private String text;
    public Document(String t) { this.text = t; }

    @Override
    public void print() {
        System.out.println(">> " + text);
    }

    public static void main(String[] args) {
        Printable p = new Document("Hello, Interface!");
        p.print();
    }
}
src/FunctionalDemo.javaJava
public class FunctionalDemo {
    @FunctionalInterface
    interface Calc {
        int apply(int a, int b);
    }

    public static void main(String[] args) {
        Calc add = (a, b) -> a + b;
        Calc mul = (a, b) -> a * b;
        Calc max = (a, b) -> a > b ? a : b;

        System.out.println("add(2,3)=" + add.apply(2, 3));
        System.out.println("mul(2,3)=" + mul.apply(2, 3));
        System.out.println("max(2,3)=" + max.apply(2, 3));
    }
}
src/MultipleInterface.javaJava
public class MultipleInterface {
    interface Flyable { void fly(); }
    interface Swimmable { void swim(); }

    static class Duck implements Flyable, Swimmable {
        @Override public void fly() { System.out.println("ducks fly"); }
        @Override public void swim() { System.out.println("duck swimming"); }
    }

    public static void main(String[] args) {
        Duck d = new Duck();
        d.fly();
        d.swim();

        Flyable f = d;
        Swimmable s = d;
        f.fly();
        s.swim();
    }
}
src/Printable.javaJava
public interface Printable {
    void print();
}

Assignment

Problem 1 — Greeting interface

  • File name: Homework01.java
  • Core concepts: interface, implements, default

Requirements

  • Abstract interface Greeting to String hello() + default String shout() (conversion to uppercase).
  • Created two implementations KoreanG and EnglishG.
  • Output the results of each hello() and shout().

Expected output

hello
Hello
hello
HELLO

Problem 2 — Filtering with a functional interface

  • File name: Homework02.java
  • Core concepts: @FunctionalInterface, lambda

Requirements

-Definition of @FunctionalInterface IntFilter { boolean test(int n); }.

  • Returns the number that satisfies the conditions with the static int countIf(int[] arr, IntFilter f) method.
  • In main, output the even number of [1..10] and the number of 5 or more.

Expected output

Even number: 5
5 or more: 6

Check the correct answer

After solving it yourself, compare it with the reference solution below.

Show the reference solution

Try the assignment yourself first — comparing your attempt with a working solution is where most of the learning happens.

Homework01.javaJava
/** Greeting interface.*/
public class Homework01 {
    public static void main(String[] args) {
        Greeting[] gs = { new KoreanG(), new EnglishG() };
        for (Greeting g : gs) System.out.println(g.hello());
        for (Greeting g : gs) System.out.println(g.shout());
    }
}

interface Greeting {
    String hello();
    default String shout() { return hello().toUpperCase(); }
}

class KoreanG implements Greeting {
    @Override public String hello() { return "hello"; }
}

class EnglishG implements Greeting {
    @Override public String hello() { return "Hello"; }
}
Homework02.javaJava
/** Counting with functional interface.*/
public class Homework02 {
    @FunctionalInterface
    interface IntFilter {
        boolean test(int n);
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        System.out.println("Even numbers:" + countIf(arr, n -> n % 2 == 0));
        System.out.println("5 or more:" + countIf(arr, n -> n >= 5));
    }

    static int countIf(int[] arr, IntFilter f) {
        int c = 0;
        for (int n : arr) if (f.test(n)) c++;
        return c;
    }
}

Learn this lesson with a mentor

Work through the Java + Spring Boot track on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now