저번 글에서는 람다식에 대해 공부했었다. 그리고 람다식은 JAVA에 새로 추가된 함수형 언어로 익명 객체를 생성한다. 객체이기 때문에 내부 메서드를 호출하려면 참조변수가 필요한데, 어떤 식으로 호출해야하는가? 이 부분에 대해서는 고민이 필요하다. 이 때 사용하는 것이 바로 함수형 인터페이스이다.
단 하나의 추상 메서드만 선언된 인터페이스를 말한다.
//보통의 인터페이스에는 여러개의 메서드를 선언해도 되지만, 함수형 인터페이서는 단 하나의 추상 메서드만 선언해야한다.
//인터페이스에는 annotaion을 붙이는 것이 좋다. 이유는 붙여야 컴파일러에서 확인을 한 번 해주기 때문이다.
@FunctionalInterface
interface MyFunction {
public abstract int max(int a, int b);
//public abstract는 생략 가능하다. 인터페이스의 모든 메서드는 무조건 public abstract이기 때문이다.
}
익명클래스의 구현
//클래스의 선언과 객체 생성을 동시에 한다.
MyFunction f = new MyFunction () {
public int max(int a, int b){
//오버라이딩 규칙 - 접근 제어자는 좁게 바꿀 수 없다. 여기서는 public 생략 불가능하다 (생략시 default로 됨)
return a > b ? a : b;
}
}
사용
int value = f.max(3,5); //myFunction안에 있는 max()를 호출
참조변수 안에 max라는 추상 메서드가 정의되어 있기 때문에 호출이 가능하다.
즉, 참조변수 안에 추상 메서드가 정의되어 있어야만 한다.
람다식으로 하게 된다면 다음과 같이 가능해진다.
//참조 변수안의 추상 메서드와 매개변수가 다르면 안된다!
MyFunction f = (a, b) -> a > b ? a : b;
int value = f.max(3, 5);
람다식을 이용해서 이름을 없앴지만 결국엔 호출해서 사용하기 위해서는 이름이 필요하다. 그래서 함수형 인터페이스를 이용해서 이름을 붙여주는 것이라고 생각하면 된다. 둘을 연결해서 사용할 수 있게 하는 것이라고 생각하면 된다!
@FunctionalInterface
interface MyFunction {
void myMethod(); //람다식에 이름을 붙여주기.
}
//메서드의 매개변수로 람다식을 받겠다.
void aMethod (MyFunction f) {
f.myMethod(); //람다식 호출(이 메서드에서 인터페이스의 이름으로 호출)
}
MyFunction f = () -> System.out.println("myMethod()");
aMethod(f);
//위의 코드를
aMethod(() -> System.out.println("myMethod()"));
//이런식으로도 가능하다!
//MyFunction 람다식을 반환한다는 뜻
MyFunction myMethod() {
MyFunction f = () -> {};
return f;
}
다음과 같이 짧게 줄여 쓸 수도 있다.
MyFunction myMethod() {
return () -> {};
}