목차
자바는 객체를 1급 시민으로 갖는다
1급 시민이란
- 변수에 담을 수 있다
- 인자로 전달할 수 있다
- 반환값으로 전달할 수 있다
다음과 같은 조건을 충족하는 것을 말하고
자바는 객체 지향 프로그래밍에 맞게
객체를 1급 시민으로 갖고 있다
하지만
함수형 프로그래밍이 대두되면서
함수를 객체로 담을 수 없는 자바는
익명 클래스
앞서 말한 함수를 1급 시민처럼
사용할 수 있게 된 배경을 알기 위해선
익명 클래스로 거슬러 올라간다
예전 알고리즘 문제를 풀 때
어떤 객체를 만들고 그 객체의 한 요소를 기준으로
정렬을 하고 싶을 때
아래와 같이 구현을 했었다
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.getScore() - s2.getScore();
}
});
위에서 사용한 Collections.sort 함수는
sort(List<T> list, Comparator<? super T> c)
위와 같은 형태를 가지며
두 번째 인자로 Comparator 인터페이스를 받는다
( 즉, Comparator 인터페이스를 구현한 객체를 받는다 )
Comparator 인터페이스를 구현한 클래스를 따로 정의할 수도 있지만
위처럼 인자가 들어가는 자리에
new 연산자 와 인터페이스 를 통해
인터페이스를 구현한 이름 없는 클래스
인 익명클래스를 만들어 그 객체를 넘길 수도 있다
일회성으로 쓸 클래스 같은 경우
이처럼 익명클래스가 자주 사용된다
함수형 인터페이스
위의 Comparator
인터페이스는
compare 함수 하나만을 추상 메서드로 갖는다
( 정확히는 equals 도 갖지만 equals은 Object의 public 함수이기에 이는 제외하고 카운트 한다 )
추상 메서드
- 구현하는 클래스가 재정의하여 그 기능을 채워 사용할 것을 강제
이처럼
단 하나의 추상 메서드를 갖는
인터페이스를 함수형 인터페이스라 하고
이런 함수형 인터페이스는 람다식으로 변환이 가능하다
람다식
Collections.sort(list, (s1, s2) -> s1.getScore() - s2.getScore());
위에서 Comparator
인터페이스로 익명클래스를 사용하여
정렬을 구현했지만
람다식을 사용하여 위처럼 간결하게 표현할 수가 있다
이런 람다식은
자바 8부터 지원하기 시작했으며
함수형 인터페이스에 한해서 변환이 가능하다
그 이유는
(s1, s2) -> s1.getScore() - s2.getScore()
위와 같은 람다식을 예로 들면
(s1, s2)
을 인자로 받고
s1.getScore() - s2.getScore()
를 리턴 한다는 뜻인데
이는
int compare(T o1, T o2);
Comparator
인터페이스의 compare
추상 메서드와 맵핑된 람다식이다
만일, Comparator
인터페이스에 추상 메서드가 또 있다면
람다식 작성
이처럼 원래
- 함수형 인터페이스를 구현한 익명클래스가 들어가던 자리에
- 추상 메서드를 구현한 람다식
이 들어갈 수가 있게 된다
때문에
람다식의 형태도 구현한
추상 메서드의 형태와 일치해야 하는데
compare
추상 메서드를 예로 들면
int compare(T o1, T o2);
- 제너릭 타입을 갖는
- 2개의 인자를 받고
- int 타입을 리턴한다
따라서, 람다식도
(s1, s2) -> s1.getScore() - s2.getScore()
(s1, s2)
- 같은 타입의 객체
- 2개를 인자로
→ s1.getScore() - s2.getScore()
- int 타입을 가지는 식을 리턴값으로 가져야 한다
람다식 사용
이렇기 때문에
자바에서는
여러 타입의 인자와 리턴 타입을 가지는
다양한 함수형 인터페이스를 지원해주고 있다
여기서
알맞은 함수형 인터페이스를 인자로 받아
그 추상메소드를 사용하면
람다식을 받아 쓰도록 구현할 수가 있다
'자바' 카테고리의 다른 글
객체 지향과 다형성 그리고 SOLID (0) | 2021.01.05 |
---|
댓글