[Java] 제네릭(Generic) 프로그래밍

Updated:

🥗 Generic

우리가 프로그래밍을 할 때 선언하는 변수는 모두 각자의 자료형을 가지고 있다.

정수를 저장하고 싶으면 int, 문자열을 저장하고 싶으면 String 처럼 말이다.

완전히 기능은 동일하지만 어떤 메소드는 정수를 사용하고, 어떤 메소드는 문자열을 사용한다면 우리는 메소드 두 개를 만들어야 한다.

하지만 변수나 메소드의 자료형을 필요에 따라 바꿀 수 있다면 메소드를 한 개만 만들어도 될 것이다.

이처럼 어떤 값이 하나의 자료형이 아닌 여러가지 자료형을 사용할 수 있도록 프로그래밍 하는 것을 제네릭 프로그래밍 이라고 한다.

🍟 Generic 프로그래밍

리플렉션이나 템플릿 메소드나 싱글톤이나.. 이런 기법들은 글로 설명을 보는 것 보다

직접 예시를 가지고 코딩을 해보는 것이 더 이해하기가 쉽다.

다음은 여러가지 재료를 가지고 프린팅을 해주는 3D 프린터를 제네릭 프로그래밍으로 구현한 예시이다.

package generic;

public class Printer <T> {
    public T material;

    public void setMaterial(T material) {
        this.material = material;
    }

    public T getMaterial() {
        return material;
    }

    public String toString() {
        return this.material.toString();
    }
}

우선 Printer 클래스 선언부를 보게 되면 <T> 라고 뒤에 무언가가 더 붙어있다.

다이아몬드 연산자와 안에 적절한 알파벳을 써주면 제네릭 클래스를 만들 수 있다.

내가 사용 할 자료형이 T 위치에 들어가 수행된다고 생각하면 된다.

물론 다이아몬드 연산자 안에 내가 알아보기 쉬운 문자를 적어도 된다.

하지만 자바 컨벤션을 보게 되면 이런식으로 작성하게 규칙을 정해주었다.

스크린샷 2020-12-20 오전 12 03 36


다음으로 프린터에 사용 될 재료인 Powder, Plastic 클래스를 만들어 보자.

package generic;

public class Powder {
    public String toString() {
        return "사용 된 재료는 Powder 입니다.";
    }
}
package generic;

public class Plastic {
    public String toString() {
        return "사용 된 재료는 Plastic 입니다.";
    }
}

만약 Printer 클래스를 제네릭 클래스로 만들지 않았더라면 이 두 가지 재료를 사용하는 프린터를 각각 구현해야 했을 것 이다.

아니면 자료형 T 로 선언되어 있는 부분을 Object 로 만들어 구현 할 수 있다.

하지만 이렇게 구현한다면 set 을 하는 경우는 자식에서 부모로 업 캐스팅이 자동으로 되지만

get 을 하는 경우에는 Object 클래스에서 각각의 재료 클래스로 다운 캐스팅을 직접 해주어야 하기 때문에 굉장히 번거롭다.


package generic;

public class Main {
    public static void main(String[] args) {
        Printer<Powder> powderPrinter = new Printer<>();
        powderPrinter.setMaterial(new Powder());
        System.out.println(powderPrinter);

        Printer<Plastic> plasticPrinter = new Printer<>();
        plasticPrinter.setMaterial(new Plastic());
        System.out.println(plasticPrinter);
    }
}

프린터를 생성 할 때 printer<Powder> 과 같이 T 의 자료형을 정해주면 된다.

생략을 해도 컴파일러가 추측을 해서 정해주지만.. 경고의 주황색 밑줄이 쳐지니 되도록이면 자료형을 정해주자.

그리고 프로그램을 실행시켜보면 하나의 프린터 클래스를 가지고 여러가지 재료를 사용 할 수 있게 되었다.

스크린샷 2020-12-20 오전 12 11 28


마지막으로 static 변수의 자료형이나 static 메소드의 내부에 있는 자료형으로 T 를 사용할 수 없다.

왜냐하면 static 변수는 인스턴스가 생성되기 전에 만들어지는데 T 의 자료형은 인스턴스가 생성 될 때 정해지기 때문이다.

그리고 Printer<T> 에 사용 할 자료형을 제한하는 Printer<T extends> 기법도 있다.



Categories:

Updated:

Leave a comment