1등급 시민 객체 (일급 객체, first-class object)

Gi Lick·2023년 7월 25일
0

이 부분에서 정말 오래 고민하고 공부하고 막혀있었다.
Java에서 객체지향만 진행하던 나에게는 정말 어려운 이론이었다.

Java에서는 흔히 사용되는 방식은 아니라는 이야기를 들었다.
하지만 코틀린을 한다면 알고 있어야 하는 내용이기도 했다.

1등급 시민 객체란?

  1. 무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.
  2. 변수나 자료구조에 저장할 수 있다.
  3. 함수의 매개변수에 전달할 수 있다.
  4. 함수의 반환값으로 사용할 수 있다.

위의 조건들을 만족해야 한다.
하나씩 무슨 의미인지 알아보도록 한다.

1. 무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.

이 내용은 우선 단어의 의미부터 알고 가야 한다.
리터럴이란

리터럴(Literal)은 프로그래밍 언어에서 고정된 값을 나타내는 표기법이다.

import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        // 람다 표현식은 무명의 리터럴로서 익명 함수로 사용됨
        Function<Integer, Integer> addOne = (x) -> x + 1;

        int result = addOne.apply(5); // 5 + 1 = 6
        System.out.println("Result: " + result);
    }
}

여기서

Function<Integer, Integer> addOne = (x) -> x + 1;

이 부분이 람다식을 이용한 무명의 레터럴을 이용하는 부분이다.
즉, (x) 는 익명의 함수를 의미하는 것이다.

java는 8버전 이후 람다식을 통한 무명의 레터럴로 생성할 수 있게 바뀌었다.

2. 변수나 자료구조에 저장할 수 있다.

이 부분이 진짜 난해했다.
아니… 변수나 자료구조에 로직을 어떻게 담아…..?

객체를 담을 수 는 있겠지만, 변수에 어떻게…? 라고 생각했는데
Java에서도 되더라….

public class Main {
    public static void main(String[] args) {
        // 두 수를 더하는 함수를 변수에 저장
        MathOperation addition = (a, b) -> a + b;

        // 두 수를 뺴는 함수를 변수에 저장
        MathOperation subtraction = (a, b) -> a - b;

        // 함수를 실행할 메소드 호출
        int result1 = addition.operate(10, 5); // 10 + 5
        int result2 = subtraction.operate(10, 5); // 10 - 5

        System.out.println("Result1: " + result1); // 15
        System.out.println("Result2: " + result2); // 5
    }

    // 함수형 인터페이스 정의
    @FunctionalInterface
    interface MathOperation {
        int operate(int a, int b);
    }
}

위와 같은 방식으로 할 수 있다.
@FunctionalInterface 어노테이션을 통해서 함수형 인터페이스 라는 것을 정의하고 각 변수에 로직을 저장할 수 있게 되는데, 이러한 방식을 통해서 Java도 함수형 프로그래밍이 가능하다.

3. 함수의 매개변수에 전달할 수 있다.

마찬가지로

public static void main(String[] args) {
        MathOperation operation = ((a, b) -> a + b);

        int result = execute(operation, 10, 5);

        System.out.println("result" + result); // 15
    }

    // 함수를 전달받아 실행하는 메소드
    private static int execute(MathOperation operation, int a, int b) {
        return operation.operate(a, b);
    }
}

// 함수형 인터페이스 정의
@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);
}

이런식으로 함수의 매게변수에 전달할 수 있으므로, 3번을 만족할 수 있다.

4. 함수의 반환값으로 사용할 수 있다.

public class Main {
    public static void main(String[] args) {
        int result = returnMath().operate(10,5);

        System.out.println("Result2: " + result); // 50
    }

		//**함수의 반환값으로 사용**할 수 있다.
    private static MathOperation returnMath() {
        return (a, b) -> a * b;
    }

    // 함수형 인터페이스 정의
    @FunctionalInterface
    interface MathOperation {
        int operate(int a, int b);
    }
}

위와 같은 방식으로 방식으로 ‘함수의 반환값으로 사용할 수 있다.’를 만족할 수 있다.

Java로 구현하다보니 신기한 것을 많이 볼 수 있었다.
이런 것 까지 된다고…? 싶었지만, 굳이 이러한 것을 내가 사용할 일이 올까? 라는 고민을 하게 되었다.
코틀린이나 Js쪽을 하게 되면 언젠가는 접하게 되는 프로그래밍 프로다임 중 하나라는데, 실무에서 얼마나 자주 사용하게 될지에 다한 의구심이 조금 들었다.

profile
뒷-끝 있는 개-발자

1개의 댓글

comment-user-thumbnail
2023년 7월 25일

개발자로서 성장하는 데 큰 도움이 된 글이었습니다. 감사합니다.

답글 달기