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

변주한·2022년 6월 30일
0

public interface Function<T, R> {

R apply(T t);

}

음...

Java1.8을 공부중이지만 민망하게도 이러한 함수형 인터페이스는 처음봤고 사실 이해도 어려웠다.

내 식대로 일단 정리를 해야겠다...

일단!

"Java 8 이상부터 기능 개선"이 있었다.

사실 1.8버전의 꽃은 stream이다. 다음 포스팅때 올릴거다

1. 인터페이스가 구현체를 가질 수 있게 된 것. = default 메소드

2. static 메소드를 가질 수 있게 되었다. : 함수 제공자가 됨.

그리고 대망의

3. Functional Inaterface

추상메소드가 하나만 존재하는 인터페이스

  • default 나 static 메소드가 있어도 상관없다.

@FunctionalInterface 을 달아준다.
-> 없어도 상관없지만 @Override와 같이 표시해줌으로써 우리는 해당 인터페이스가 함수형인터페이스임을 명시하고 함수형인터페이스의 문법에 어긋나는 행위를 막아줄수 있다.
ex)

  @FunctionalInterface
  public interface MyRunnable {
      void run();
  }
  
  ///----
  
  public static void main(String[] args) {
      MyRunnable r = new MyRunnable() {
            @Override
            public void run() {
            	System.out.println("nanana");
            };
         }
     };
     r.run();
  }

한번 Ruunable 인터페이스를 짜봤는데 대충 어떻게 쓰는지 익명클래스 정의를 해봤다면 이해가 될거라 생각된다.

대표적인 함수형 인터페이스

입력 → 출력추상메소드
ConsumerT → voidvoid accept(T t)
FunctionT → RR apply(T t)
PredicateT → booleanboolean test(T t)
Supplier( ) → TT get()
Runnable( ) → voidvoid run()
Comparator(T, T) → intint compare(T o1, T o2)

이외에 많은 함수형 인터페이스들이 있지만 요 친구들은 필수적으로 알고 제법 능숙하게 쓸 수 있어야만한다.

근데 입력 → 출력 열에 표현된 형식, 저건뭔가...
뭐 화살표 하고 하는데 이게 소스코드에 주석도 아니고...
저게 뭐냐면!

Lambda 표현식

  • 익명 메소드를 사용해서 간결한 인터페이스 인스턴스 생성 방법.
  • FunctionalInterface 에서 가능.
  • 간결하게 표현 가능.

그래 lambda가 뭔지 글로는 이해했고 어떻게 사용할까? 간단하다.

public static void main(String[] args) {
	MyRunnable r = new MyRunnable() {
        @Override
        public void run() {
            System.out.println("nanana");
        };
	}
};
	r.run();
}

앞서 정의했던 요 친구는 이렇게 바뀔수 있다는 것이다.

public static void main(String[] args) {
	MyRunnable r = () -> {
            System.out.println("nanana");
	};
	r.run();
}

답이 보이는 퀴즈! default 메소드 3개와 static 메소드 1개 그리고 추상메서드 1개로 이루어져 있는 interface가 있다면 해당 interface는 함수형 인터페이스라고 말 할 수 있는가?

정답: Yes

까먹었을까봐 복기하고 지나간다. default, static method가 몇개가 있든 추상메서드는 하나만 있으면 그건 함수형 인터페이스가 된다.

추가적으로 이런 함수형 인터페이스에서 받은 인자를 "메소드 레퍼런스"를 사용해서 원하는 형태로 만들곤 하는데

4. 메소드 레퍼런스

람다 표현식에서 입력되는 값을 변경없이 바로 사용하는 경우 최종으로 적용될 메소드에 레퍼런스를 지정해 주는 표현 방식.

Consumer<String> func = text -> System.out.println(text);

Consumer<String> func = System.out::println;

위의 두 표현은 정확히 같은 표현이다.

메소드 레퍼런스를 쓰면 좋은 이유는 유지보수시에 암묵적으로

입력값을 변경하지 말라는 표현방식이기도 하다.

개발자의 개입을 차단함으로써 안정성을 얻을 수 있다.

무엇보다 함수적 인터페이스lambda 식이든 메소드 레퍼런스

가장 좋은건 계속 써보고 IDE의 도움을 받아 이러한 예제들을 자주보는것이 도움이 된다.

profile
늦었지만 꾸준히

0개의 댓글