ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 람다와 스트림 - 함수형 인터페이스
    백엔드/자바 2021. 8. 24. 13:25

    람다와 익명 객체()

     

    람다와 스트림 - 람다식의 정의

    람다식(Lambda Expression)이란? 자바 관련 예제를 보다보면 위와 같은 식을 코드를 볼 수 있다. 메서드들을 체이닝으로 이어준 것인데, 그 중에서도 filter() 메서드 안을 보면 특이한 코드를 볼 수 있

    sgcomputer.tistory.com

     

    이전 파트에서 말해듯 람다식의 가장 큰 특징이라하면 이름이 없다는 것을 꼽을 수 있다.

     

    그리고 이름이 없으므로 람다식은 익명 함수라고 한 바 있다.

     

    하지만 엄밀히 말하면 자바에서 람다는 익명 함수가 아닌 익명 객체라 할 수 있다.

     

    왜냐면 자바에서 함수(메서드)는 단독으로 존재할 수 없기 때문이다.

     

    코드로 보면서 설명을 보면 더 이해하기 쉬울 것이다.

     

     

     

    왼쪽과 같이 이름이 없는 람다식이 있다고 가정해보자.

     

    람다식을 얼핏 보면 단독으로 존재하는 함수 혹은 메서드같다.

     

    하지만 실제로 이 람다식은 오른쪽처럼 Object 클래스를 상속받아 구현한 익명 클래스(익명 객체)를

     

    간략하게 표현한 것으로 두 코드는 동일하다고 보면 된다.

     

    즉 람다는 단독으로 쓰이는 함수같지만 실제로는 Object 클래스 혹은 어떤 부모 클래스, 인터페이스를

     

    상속하거나 구현해서 만들어진 익명 클래스나 익명 함수를 요약해서 만들때 사용하는 식인 것이다.

     

    그래서 자바에서 람다는 단독으로 쓰이는 익명 함수가 아닌 익명 클래스, 익명 객체인 것이다.

     

    이해가 안된다면 아래 사용법까지 쭈욱 한번 보기로 하자.

    람다의 사용 

    위에서 말했듯 람다식은 익명 객체를 간략화한 것이다.

     

    그렇다면 이 익명 객체를 사용하기 위해선 어떻게 해야할까?

     

     

     

    바로 위와 같이 참조 변수가 필요하다.

     

    해당 익명 함수는 별다른 부모클래스, 인터페이스가 없고 Object를 상속 받았다.

     

    그러므로 Object 타입의 참조 변수를 이용하면 해당 익명 객체를 저장할 수 있다.

     

     

     

    하지만 실제로 해당 익명 객체의 max() 메서드를 이용하려면 컴파일 에러가 나는 것을 볼 수 있다.

     

    왜냐고? 익명 객체가 상속 받은 부모 클래스 Object는 max()메서드를 가지고 있기 않기 때문이다.

     

    클래스 상속에 대해 배웠다면 알겠지만 부모 클래스를 타입으로 갖는 참조 변수는

     

    자손 클래스의 객체를 저장만 할 수 있을 뿐 자손의 요소를 쓸 수 없는 것을 기억할 것이다.

     

    여기서도 Object 타입의 참조 변수는 익명 객체가 Object의 자손이므로 저장만 가능할 뿐

     

    익명 객체의 요소들을 사용 할 수 없음을 확인할 수 있다.

     

    그렇다면 익명 객체를 사용하려면 어떻게 해야할까? 바로 함수형 인터페이스를 이용하면 된다.

    함수형 인터페이스란?

    함수형 인터페이란 단 하나의 메서드만 선언된 인터페이스를 말한다.

     

    이 함수형 인터페이스를 이용하면 익명 객체의 사용이 가능하다.

     

     

     

    예를 들어 위와 같은 메서드가 익명 함수 내에 있다고 가정해보자.

     

    만약 익명함수 안에 있는 max()와 같은 메서드를 사용하고 싶다면 함수형 인터페이스를 만들어야 한다.

     

     

     

    위와 같이 메인 함수 밖에 함수형 인터페이스를 만들어준다.(이름은 마음대로)

     

    만들 때 함수형 인터페이스는 메서드를 하나만 가질 수 있다는 점만 주의하면 된다.

     

    함수형 인터페이스를 만들었다면 그 안에 max() 메서드를 선언해준다.

     

     

     

    그 다음은 함수형 인터페이스를 구현한 익명 객체를 만들면 된다.

     

    함수형 인터페이스 익명 객체를 만들 때 max()를 오버라이딩해서 내용을 채워준다.

     

    그리고나서 해당 객체를 TestInter 즉 함수형 인터페이스를 타입으로 하는 참조변수에 저장한다.

     

     

     

    그 다음엔 저장한 참조변수를 이용해서 위와 같이 max()를 사용하면 된다.

     

    Object를 상속받아서 익명 객체를 만들고 써줄때와 달리

     

    이때는 함수형 인터페이스가 같은 max()를 가지고 있기 때문에 사용이 가능한 것이다.

     

    하지만 이때쯤 이상한 생각이 들 것이다.

     

    그래서 람다는 언제써주는가?

     

    그래서 람다랑 함수형 인터페이스는 무슨 관계인가?

     

    당연히 관계가 있다.

    함수형 인터페이스의 익명 객체와 람다식 사용하기

     

    이전 단락에서 함수형 인터페이스를 선언하고 이를 실행하는 방법까지 알아봤다.

     

    그래서 이게 람다랑 무슨 상관인가 싶을 것이다.

     

    이제 익명 객체를 간략하게 표현해보자.

     

     

     

    참조 변수 뒤에 덕지 덕지 붙어있던 익명 객체를 람다로 아주 간단하게 나타냈다.

     

     

     

    그리고 이렇게 줄여도 당연히 이전과 똑같이 잘 작동한다.

     

    이전 파트와 지금까지 람다를 설명하면서 람다는 메서드를 줄여준다고 했는데,

     

    조금 더 자세히 설명하자면 람다식은 익명 함수, 익명 객체를 간략하게 나타내기 위한 것이다.

     

    즉 이전처럼 익명객체를 표현하면 이해하기도 힘들도 코드가 더러워지기 때문에

     

    이를 간단하게 나타내려고 람다식을 사용하는 것이다.

     

    그리고 만든 람다식도 이전에 써준 익명객체 코드와 동일하게 작동하기 때문에 사용법도 같다.

     

    람다식 안에 max() 메서드를 따로 쓰진 않았지만, 우리가 쓴 람다식이 max() 메서드에 자동 매칭되므로

     

    참조변수를 통해 max()를 써주면 정상적으로 작동하는 것이다.

     

Designed by Tistory.