Menu
Coddy logo textTech

제네릭 클래스

Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 87개 중 54번째.

이제 제네릭이 왜 유용한지 이해하셨으니, 여러분만의 제네릭 클래스를 만들어 보겠습니다. 제네릭 클래스는 클래스 이름 뒤의 꺾쇠괄호 안에 하나 이상의 타입 매개변수를 선언하며, 이는 클래스 전체에서 사용될 수 있습니다.

class Box<T> {
    private T content;
    
    public void set(T content) {
        this.content = content;
    }
    
    public T get() {
        return content;
    }
}

T는 타입 매개변수입니다. 이는 인스턴스를 생성할 때 실제 타입으로 대체되는 자리표시자입니다. 어떤 이름이든 사용할 수 있지만, 관례적으로 단일 대문자를 사용합니다: Type을 위한 T, Element를 위한 E, Key를 위한 K, Value를 위한 V.

제네릭 클래스를 인스턴스화할 때, 꺾쇠괄호 안에 실제 타입을 지정합니다:

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get();  // 캐스팅이 필요하지 않음

Box<Integer> intBox = new Box<>();
intBox.set(42);
Integer num = intBox.get();

오른쪽의 <> (다이아몬드 연산자)를 확인하세요. Java는 선언부로부터 타입을 추론합니다. 또한 둘 이상의 타입으로 작업해야 하는 클래스의 경우 여러 개의 타입 파라미터를 사용할 수도 있습니다:

class Pair<K, V> {
    private K key;
    private V value;
    
    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }
    
    public K getKey() { return key; }
    public V getValue() { return value; }
}

Pair<String, Integer> pair = new Pair<>("age", 25);
challenge icon

챌린지

쉬움

제네릭 클래스의 강력함을 보여주는 선물 등록 시스템을 구축해 봅시다. 모든 유형의 선물 아이템을 담을 수 있는 유연한 저장 시스템과, 여러 타입 매개변수를 사용하여 선물 이름과 세부 정보를 연결하는 등록부를 만들 것입니다.

코드는 세 개의 파일로 구성됩니다:

  • GiftBox.java: 모든 유형의 선물을 포장할 수 있는 제네릭 클래스를 만듭니다. GiftBox<T>T 타입의 private 필드 itemfalse로 시작하는 private 필드 wrapped (boolean)를 가져야 합니다. 아이템을 받는 생성자, 아이템을 반환하는 getItem() 메서드, wrapped를 true로 설정하는 wrap() 메서드, 그리고 포장 상태를 반환하는 isWrapped() 메서드를 포함하세요. 포장 상태에 따라 [item] (wrapped) 또는 [item] (unwrapped)를 반환하는 getStatus() 메서드를 추가하세요.
  • Registry.java: 수령인과 선물을 연결하는 두 개의 타입 매개변수를 가진 제네릭 클래스를 만듭니다. Registry<K, V>K 타입의 private 필드 recipientV 타입의 private 필드 gift를 가져야 합니다. 두 값을 모두 받는 생성자, 게터 메서드인 getRecipient()getGift(), 그리고 [recipient] -> [gift]를 반환하는 getEntry() 메서드를 포함하세요.
  • Main.java: 선물 등록 시스템을 실제로 작동시켜 보세요! 수령인 이름(String), 선물 설명(String), 선물 가치(달러를 나타내는 정수)의 세 가지 입력을 받게 됩니다.

    먼저, 선물 설명을 포함하는 GiftBox<String>을 생성합니다. wrap() 메서드를 사용하여 포장한 다음, 그 상태를 출력하세요.

    다음으로, 선물 가치(기프트 카드 금액을 나타냄)를 포함하는 GiftBox<Integer>를 생성합니다. 이것은 포장하지 말고, 포장되지 않은 상태임을 보여주기 위해 상태를 출력하세요.

    마지막으로, 수령인 이름과 선물 설명을 연결하는 Registry<String, String>을 생성하고 등록 항목을 출력하세요.

수령인 이름, 선물 설명, 선물 가치(정수) 순서대로 세 개의 입력을 받게 됩니다.

동일한 GiftBox 클래스가 StringInteger 타입 모두에서 어떻게 원활하게 작동하는지 확인해 보세요. 이것이 바로 제네릭의 아름다움입니다! 또한 Registry 클래스는 여러 타입 매개변수를 통해 두 타입 간의 유연한 쌍을 만드는 방법을 보여줍니다.

치트 시트

제네릭 클래스(generic class)는 클래스 이름 뒤의 꺾쇠괄호 안에 하나 이상의 타입 매개변수를 선언하며, 이는 클래스 전체에서 사용할 수 있습니다:

class Box<T> {
    private T content;
    
    public void set(T content) {
        this.content = content;
    }
    
    public T get() {
        return content;
    }
}

T는 타입 매개변수입니다. 이는 인스턴스를 생성할 때 실제 타입으로 대체되는 플레이스홀더입니다. 일반적인 관례에 따라 단일 대문자를 사용합니다: T는 타입(Type), E는 요소(Element), K는 키(Key), V는 값(Value)을 의미합니다.

제네릭 클래스를 인스턴스화할 때는 꺾쇠괄호 안에 실제 타입을 지정합니다:

Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get();  // No casting needed

Box<Integer> intBox = new Box<>();
intBox.set(42);
Integer num = intBox.get();

<> (다이아몬드 연산자)를 사용하면 Java가 선언부로부터 타입을 추론할 수 있습니다.

하나 이상의 타입을 다루는 클래스의 경우 여러 개의 타입 매개변수를 사용하세요:

class Pair<K, V> {
    private K key;
    private V value;
    
    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }
    
    public K getKey() { return key; }
    public V getValue() { return value; }
}

Pair<String, Integer> pair = new Pair<>("age", 25);

직접 해보기

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 입력 읽기
        String recipientName = scanner.nextLine();
        String giftDescription = scanner.nextLine();
        int giftValue = scanner.nextInt();
        
        // TODO: gift description을 포함하는 GiftBox<String> 생성
        // TODO: wrap() 메서드를 사용하여 포장하기
        // TODO: getStatus()를 사용하여 상태 출력하기
        
        // TODO: gift value를 포함하는 GiftBox<Integer> 생성
        // TODO: 이것은 포장하지 말고 상태를 출력하기 (unwrapped로 표시되어야 함)
        
        // TODO: 수령인과 gift description을 쌍으로 하는 Registry<String, String> 생성
        // TODO: getEntry()를 사용하여 레지스트리 항목 출력하기
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨