JAVA8 이후로 인터페이스 내부의 default method 와 static method를 선언 가능하다.
[단, 인터페이스는 class와 달리 위계구조가 없으므로 접근 제어자를 설정 불가능 (항상, public으로 취급)]
/* 함수형 인터페이스 예시 */
@FunctionalInterface // 컴파일 타임에 SAM인지 판단. 아닐 경우 Compile Error
public interface SomeFunctionalInterface {
public void doSomething();
public default void sayHello() {
System.out.println("hello");
}
public static void sayBye() {
System.out.println("bye");
}
}
메소드를 수학적인 함수와 동일하게 취급하므로서, 누릴 수 있는 이점 때문에 사용한다.
프로그래밍의 패러다임이 변화하면서, 행위 그 자체도 런타임에 유연하게 변경되어야 할 필요성이 대두되었다.
행위 자체를 메소드로 표현하여, 그것을 다른 메소드로 전달할 수 있는 방법이 필요했다. 하지만, 자바의 메소드는 일급 객체가 아니였기 때문에 이러한 역할을 수행할 수 있는 다른 매개체가 필요했는데 이것이 함수형 인터페이스
이다.
// 해당 클래스를 외부에 정의하여, 생성자나 팩토리를 이용하여 생성하는 방법
public class OuterClass implements SomeFunctionalInterface {
@Override
public void doSomething() {
System.out.println("~~ㅇㅅㅇ~~");
}
}
이 방법은 어느 인터페이스에서나 흔히 접할 수 있는 방법이다. 주로, 재사용성이 높을 경우 사용한다.
public class Main {
public static void main(String[] args) {
// 익명 클래스 활용
SomeFunctionalInterface impl = new SomeFunctionalInterface {
@Override
public void doSomething() {
System.out.println("~~aㅅa~~");
}
}
}
}
실제로 위 방법은, 자바8 이전에 많이 쓰였던 방법이다. 주로 재사용성이 떨어지는 행위를 표현하기 위하여 많이 사용하였다.
자바8 이후로 더 나은 방법이 존재한다. 아래를 살펴보자
public class Main {
public static void main(String[] args) {
// 람다 활용
SomeFunctionalInterface impl = () -> System.out.println("~~ㅁㅅㅁ~~");
}
}
내부 익명 클래스와 비교해보면, 람다식이 더 직관적이고 간결하다는 것을 확인해볼 수 있다.
Java8 이후로는 이러한 람다식을 언어 자체에서 지원한다.
람다의 리턴 값은 함수형 인터페이스
이다. 특정한 행위
를 인라인 형식으로 표현하는 람다식은 함수형 인터페이스와 완벽하게 호환된다.
내부 클래스든 외부 클래스든 클래스는 자신만의 고유한 Scope를 가진다.
그에 비해서, 람다식은 해당 람다식을 정의한 클래스의 Scope에서 정의되므로 고유한 Scope를 가지지 않는다.
이 때문에, 람다식 내부에서는 람다식을 선언한 외부 클래스에서 사용하는 변수와 동일한 이름을 가진 변수를 선언할 수 없다.
레퍼런스
흔히 많이 사용할 법한 함수형 인터페이스들은 자바에서 직접 제공해주고있다.
이 중, 몇몇은 특정 함수형 인터페이스의 확장판(?)이다. 가장 많이 쓰이는 함수형 인터페이스를 살펴보자.
Predicate<T>
: T
타입의 인자를 받아서 boolean을 리턴하는 함수형 인터페이스Consumer<T>
: T
타입의 인자를 받아서 void를 리턴하는 함수형 인터페이스Supplier<T>
: 아무런 인자를 받지 않고 T
타입의 인자를 리턴하는 함수형 인터페이스Function<T,R>
: T
타입의 단일 인자를 받아서 R
타입의 인자를 반환하는 함수형 인터페이스etc) 그 외 Bi~~
, Unary~~
라는 접두사를 사용하는 함수형 인터페이스는 기존 ~~라는 함수형 인터페이스에서 특수한 성질이 추가된 함수형 인터페이스이다.
Unary~~
: 입력 값과 리턴 값의 인자 타입이 같다.Bi~~
: 입력 값이 단일 인자가 아닌 2개의 인자로 구성되어있다.