Java

[Java] 익명클래스, 함수형 인터페이스, 익명함수(람다식)

goblin- 2024. 10. 5. 00:59

익명 클래스(Anonymous Class)

 

익명 클래스는 이름이 없는 클래스로, 한 번만 사용되거나 간단한 기능을 구현할 때 사용됩니다. 익명 클래스는 인터페이스나 추상 클래스를 즉시 구현하거나 확장하는 데 사용됩니다.

 

익명 클래스의 특징

 

1. 이름 없음: 클래스를 정의하면서 바로 인스턴스를 생성하는 방식으로, 클래스 이름이 없습니다.

2. 재사용 불가: 익명 클래스는 한 번 정의되고 나면 재사용할 수 없습니다.

3. 즉석에서 정의: 인터페이스나 추상 클래스의 구현체를 한 번만 정의하고 사용할 때 주로 사용됩니다.

4. 복잡한 구현 가능: 하나 이상의 메서드를 포함하거나 여러 개의 메서드를 구현할 수 있습니다.

 

익명 클래스 예시

public class Main {
    public static void main(String[] args) {
        // Runnable 인터페이스를 익명 클래스로 구현
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("익명 클래스를 사용하여 실행됩니다.");
            }
        };
        runnable.run();  // 출력: 익명 클래스를 사용하여 실행됩니다.
    }
}

이 예시에서는 Runnable 인터페이스를 구현하는 익명 클래스를 정의하고, 그 안에서 run() 메서드를 오버라이드합니다. 이렇게 정의된 익명 클래스는 한 번만 사용됩니다.

 

람다식(익명 함수, Lambda Expression)

 

**람다식(Lambda Expression)**은 자바 8부터 도입된 익명 함수를 표현하는 간결한 방식입니다. 주로 **함수형 인터페이스(Functional Interface)**를 구현할 때 사용되며, 코드를 간결하고 직관적으로 작성할 수 있습니다.

 

람다식의 특징

 

1. 간결성: 익명 클래스보다 훨씬 간결하게 함수를 표현할 수 있습니다.

2. 함수형 인터페이스: 하나의 추상 메서드만을 가진 함수형 인터페이스를 구현할 때만 사용할 수 있습니다.

3. 함수처럼 사용: 람다식은 이름이 없는 함수를 정의한 것과 동일하며, 해당 인터페이스의 메서드를 구현합니다.

4. 함수형 프로그래밍 지원: 자바의 스트림 API와 함께 사용하여 데이터를 선언적으로 처리할 수 있습니다.

 

람다식 예시

public class Main {
    public static void main(String[] args) {
        // 함수형 인터페이스를 람다식으로 구현
        Runnable runnable = () -> System.out.println("람다식을 사용하여 실행됩니다.");
        runnable.run();  // 출력: 람다식을 사용하여 실행됩니다.
    }
}

이 코드는 익명 클래스와 동일한 기능을 하지만, 훨씬 더 간결하게 표현됩니다. 람다식은 함수형 인터페이스의 추상 메서드를 구현한 익명 함수의 일종입니다.

 

익명 클래스와 람다식 비교

특징 익명 클래스(Anonymous Class) 람다식(Lambda Expression)
정의 방식 클래스 이름 없이 인터페이스/추상 클래스를 구현 함수형 인터페이스의 추상 메서드를 간결하게 구현
복잡한 구현 가능 여러 메서드를 구현하거나 상태를 가질 수 있음 하나의 추상 메서드를 구현(단일 메서드 인터페이스에 적합)
코드의 간결성 코드가 비교적 복잡하고 길어질 수 있음 매우 간결하게 작성 가능
사용 제한 모든 인터페이스와 클래스 구현 가능 함수형 인터페이스(하나의 추상 메서드)만 구현 가능
사용 예  이벤트 리스너, 콜백 함수 등  스트림 API, 간단한 콜백 처리 등

 

익명 클래스 예시

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("익명 클래스를 사용한 구현");
    }
};
runnable.run();

 

람다식 예시

Runnable runnable = () -> System.out.println("람다식을 사용한 구현");
runnable.run();

람다식은 익명 클래스의 간결한 대체 방식입니다. 하지만, 람다식은 함수형 인터페이스(하나의 추상 메서드만을 가진 인터페이스)와 함께 사용할 수 있는 제약이 있습니다.

 

익명 클래스와 람다식의 선택

 

복잡한 로직: 여러 메서드를 구현하거나 상태가 필요한 경우 익명 클래스를 사용합니다.

간단한 작업: 하나의 추상 메서드를 간단하게 구현하려면 람다식이 훨씬 적합합니다.

 

람다식은 코드의 간결성을 제공하며, 주로 자바 8의 스트림 API와 같은 함수형 프로그래밍 문법에서 자주 사용됩니다. 익명 클래스는 여전히 복잡한 구현이 필요한 상황에서 유용하게 사용됩니다.

 

함수형 인터페이스(Functional Interface)

 

람다식을 사용하려면 반드시 함수형 인터페이스가 필요합니다. 함수형 인터페이스는 하나의 추상 메서드를 가진 인터페이스로, 람다식이 이 인터페이스의 메서드를 구현하게 됩니다.

 

함수형 인터페이스 예시

@FunctionalInterface
public interface MyFunction {
    void execute();
}

람다식을 통해 MyFunction 인터페이스의 execute() 메서드를 간단하게 구현할 수 있습니다.

MyFunction myFunction = () -> System.out.println("람다식으로 함수형 인터페이스 구현");
myFunction.execute();  // 출력: 람다식으로 함수형 인터페이스 구현

자바는 @FunctionalInterface 어노테이션을 사용하여 함수형 인터페이스임을 명시할 수 있으며, 함수형 인터페이스는 하나의 추상 메서드만 가질 수 있습니다.

 

결론

 

익명 클래스는 이름 없이 인터페이스나 추상 클래스를 즉시 구현하는 방법으로, 복잡한 구현을 지원합니다.

**람다식(익명 함수)**은 함수형 인터페이스를 간결하게 구현하는 표현식으로, 단일 추상 메서드를 가진 인터페이스를 매우 간단하게 구현할 수 있습니다.

두 방식 모두 익명 객체를 생성하는 데 사용되며, 복잡한 구현이 필요한 경우에는 익명 클래스, 간단한 함수형 인터페이스 구현이 필요한 경우에는 람다식을 사용하는 것이 적합합니다.