추상 메소드가 오로지 단 한 개만 있는 인터페이스다.
SAM(Single Abstract Method) 인터페이스다.
@FuncationInterface 어노테이션을 가지고 있는 인터페이스다.
public interface RunSomething {
void doIt();
static void printName() {
System.out.println("Hyunsik");
}
default void printAge() {
System.out.println("27");
}
}
--> 정답 : 맞다
RunSomething 인터페이스는 static 메소드도 있고 default 메소드도 있지만 추상메소드는 단 한 개이기 때문에 함수형 인터페이스가 맞다.
JAVA에서 지원해주는 @FunctionalInterface를 이용하여 함수형 인터페이스를 나타낼 수 있다.
만약 함수형 인터페이스의 자격이 상실 하였을 경우 (예를들어 추상메소드가 2개 라던가...) @FunctionalInterface밑에 밑줄이 쳐지게 된다.
추상 메소드를 딱 하나만 가지고 있는 인터페이스
코드를 줄일 수 있다.
메소드 매개변수, 리턴 타입, 변수로 만들어 사용 할 수도 있다.
public class Foo {
public static void main(String[] args) {
// 익명 내부 클래스 anonymous inner class
RunSomething runSomething = new RunSomething() {
@Override
public void doIt() {
System.out.println("Hello");
}
};
}
}
자바8 이전에는 함수형 인터페이스를 사용할 때 위에 처럼 익명 내부 클래스로 구현체를 만들어서 사용을 했었는데 자바8 이후부터는
public class Foo {
public static void main(String[] args) {
// 익명 내부 클래스 anonymous inner class
RunSomething runSomething = () -> System.out.println("Hello");
runSomething.doIt();
}
}
위와 같이 함수형 인터페이스를 줄여 쓸 수 있게 되었다.
이렇게 만든 함수를 runSomething.doIt() 처럼 실행 할 수 도 있다.
이렇게 만든 람다 표현식은 Java에서 함수형 인터페이스를 Inline으로 구현한 Object로 볼 수 있는데 이런 형태가 함수 처럼 보이기 때문에 우리는 () -> System.out.println("Hello") 이런식으로 썼지만 Java라는 언어는 객체지향 언어이기 때문에 () -> System.out.println("Hello")를 변수에 할당하고 메소드의 파라미터로 전달하고 리턴타입으로 리턴할 수 있다.
public static void main(String[] args) {
// 익명 내부 클래스 anonymous inner class
RunSomething runSomething = (number) -> number + 10;
System.out.println(runSomething.doIt(1));
System.out.println(runSomething.doIt(1));
System.out.println(runSomething.doIt(1));
}
위와 같이 입력 받은 값이 동일한 경우 결과 값이 모두 같아야 한다. ex) 1을 넣었으면 11이 나와야한다.
이것을 만족하지 못하면 함수형 프로그래밍으라고 부를 수 없다.
public class Foo {
public static void main(String[] args) {
// 익명 내부 클래스 anonymous inner class
RunSomething runSomething = new RunSomething() {
int baseNumber = 10;
@Override
public int doIt(int number) {
return number + baseNumber;
}
};
}
}
또한 위의 코드처럼 int baseNumber = 10과 같은 상태 값(함수 외부에 있는 값)을 가지고 있으면 순수 함수가 아니다.
public class Foo {
public static void main(String[] args) {
// 익명 내부 클래스 anonymous inner class
RunSomething runSomething = new RunSomething() {
int baseNumber = 10;
@Override
public int doIt(int number) {
baseNumber ++;
return number + baseNumber;
}
};
}
}
위의 코드를 보면 함수 외부의 값 baseNumber의 값이 10->11->12처럼 점점 늘어나는데 이처럼 함수 외부의 값을 변경하려고 하는 경우에도 순수 함수라고 부를 수 없다.