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개의 인자로 구성되어있다.