인프런 커뮤니티 질문&답변

최은희님의 프로필 이미지
최은희

작성한 질문수

나도코딩의 자바 기본편 - 풀코스 (20시간)

함수형 인터페이스 (전반전)

질문있습니다

작성

·

247

0

 

convertUSD(converter, 2);

강의 내용 중 위의 코드가

다시 아래의 코드로 변하던데, 이부분이 이해가 되지 않습니다.

   convertUSD(public void convert(int USD) { 		
System.out.println(USD + " 달러 = " 
+ (USD * 1400) + " 원"); }, 2);

converter은 객체이고, 아래의 코드는 함수인데 왜 이꼴이 되는걸까요?

 

답변 1

0

나도코딩님의 프로필 이미지
나도코딩
지식공유자

안녕하세요?
먼저 convertUSD() 메소드를 호출할 때 첫 번째 전달값인 Convertible 을 처음에는 KRWConverter 클래스 객체인 converter 로 전달하였습니다. 그리고 메소드 내에서는 KRWConverter 에 정의된 convert() 메소드를 호출하였지요.

그리고 우리가 정의한 Convertible 인터페이스는 다음과 같이

@FunctionalInterface
public interface Convertible {
    void convert(int USD);
}

앞에 @FunctionalInterface 가 붙어있으며 이는 함수형 인터페이스임을 뜻합니다. 수업에도 다루었던 것처럼 함수형 인터페이스는 선언과 동시에 람다식 형태로 구현을 하게 되면 해당 람다식의 동작이 인터페이스 내에 선언되어 있는 딱 하나의 추상 메소드, 우리 예제에서는 convert(int USD) 메소드와 1:1 맵핑이 되어서 convert() 를 호출하게 되면 앞에서 구현한 람다식의 동작이 수행됩니다. 함수형 인터페이스의 주요 목적이 람다식을 사용하여 메소드를 객체로 간결하게 표현하는 것입니다.

convertUSD() 로 전달하는 converter 객체는 KRWConverter 클래스로부터 생성되었으며 이는 Convertible 인터페이스를 구현하기 때문에 다형성에 의해 사용이 가능합니다. 그리고 convertUSD() 내에서는 convert() 메소드를 호출하고 있지요.

이 부분을 KRWConverter 에 구현된 convert() 메소드가 아닌, 별도의 람다식으로 구현한 동작을 수행하게끔 변환하는 과정입니다. 목표는 동일한 동작을 하는 것이므로 KRWConverter 에 구현된 convert() 메소드의 동작, 즉

public void convert(int USD) {
    // 1 달러 = 1400 원
    System.out.println(USD + " 달러 = " + (USD * 1400) + " 원");
}

이 부분을 람다식으로 변환해서 바로 convertUSD() 의 전달값으로 사용해보고자 하는 것이죠.

이 과정에서 public, void, convert, int 등 생략 가능한 부분은 모두 제외하고 다음과 같이 코드를 작성하였습니다.

// 기존 코드
convertUSD(converter, 2);

// 수정된 코드
convertUSD((USD) -> System.out.println(USD + " 달러 = " + (USD * 1400) + " 원"), 1);

결국 converter 부분이 ((USD) -> System.out.println(USD + " 달러 = " + (USD * 1400) + " 원") 로 바뀌게 되었으며 이는 convertUSD() 의 첫 번째 매개변수인 Convertible converter 가 받게 되는 것입니다.

메소드 호출이 아닌 그냥 함수형 인터페이스 정의를 하는 입장에서 본다면 다음과 동일한 코드가 되는 것이죠.

Convertible converter = ((USD) -> System.out.println(USD + " 달러 = " + (USD * 1400) + " 원”);

converter 라는 함수형 인터페이스의 동작을 람다식으로 정의를 하였고 이는 Convertible 인터페이스의 convert() 메소드와 대응되므로 convertUSD() 메소드 내에서는 converter.convert() 와 같이 하게 되면 결국 람다식에 정의된 동작이 구현되는 것입니다.

함수형 인터페이스의 개념이 지금까지 사용하던 인터페이스와는 달라서 어렵게 느껴질 수 있을 거에요. convertUSD() 메소드를 사용하는데 어떤 식으로 화폐 단위를 변환할지에 대한 동작을 정의해서 전달한다는 개념으로 이해하시면 되겠습니다. 그러면 경우에 따라 USD 를 KRW 로, 또는 새로운 converter 를 구현하여 다른 국가의 화폐 단위로 다양하게 변환을 할 수 있게 될 것입니다. Converter 만 바뀔 뿐 convertUSD 는 딱 한 번만 정의를 해두면 되는 것이죠.

아래 몇 가지 예시 코드 및 실행 결과를 살펴봐주시면 감사하겠습니다. 공간이 조금 좁아서 (USD) 뒷부분은 줄바꿈 하였습니다.

@FunctionalInterface
interface Convertible {
    void convert(int USD);
}

public class Sample {
    public static void main(String[] args) {
        Convertible KRWConverter = (USD) 
            -> System.out.println(USD + " 달러 = " + (USD * 1300) + " 원 (대한민국)");
        convertUSD(KRWConverter, 2);

        Convertible JPYConverter = (USD) 
            -> System.out.println(USD + " 달러 = " + (USD * 141) + " 엔 (일본)");
        convertUSD(JPYConverter, 2);

        Convertible CNYConverter = (USD) 
            -> System.out.println(USD + " 달러 = " + (USD * 7) + " 위안 (중국)");
        convertUSD(CNYConverter, 2);
    }

    public static void convertUSD(Convertible converter, int USD) {
        converter.convert(USD);
    }
}

(실행 결과)

2 달러 = 2600 원 (대한민국)
2 달러 = 282 엔 (일본)
2 달러 = 14 위안 (중국)

궁금증 해결에 도움되길 바라겠습니다 😊
감사합니다.

최은희님의 프로필 이미지
최은희

작성한 질문수

질문하기