제네릭 프로그래밍(Generic programming)이란 변수의 선언이나 메서드의 매개변수를 하나의 참조 자료형이 아닌 여러 자료형이 변환될 수 있도록 프로그래밍 하는 방식이다. 클래스의 속성과 기능의 종류는 같지만 참조 자료형만 다른 경우에 제네릭 프로그래밍 방식을 이용한다. 실제 사용되는 참조 자료형으로의 변환은 컬파일러가 검증하기 때문에 안정적인 프로그래밍 방식이고, 컬렉션 프레임워크에서 많이 사용되고 있다.
여러 참조 자료형으로 대체될 수 있는 부분을 하나의 문자로 표현한다. 이때 이 문자를 자료형 매개변수라고 한다.
아래는 제네릭 클래스 정의 예제이다.
public class ThreeDPrinter<T extends Material> {
private T material;
public T getMaterial() {
return material;
}
public void setMaterial(T material) {
this.material = material;
}
public String toString() {
return material.toString();
}
public void printing() {
material.doPrinting();
}
}
위 예제에서 T가 자료형 매개변수이고 'extends Material'을 통해 자료형 매개변수로 받을 참조 자료형을 제한하고 있다. Material abstract class는 자료형 매개변수로 받을 참조 자료형의 설계 목적으로 작성하였다. 이처럼 상속을 이용하여 참조 자료형을 제한하는 방법이 있다.
아래는 Material class이다.
public abstract class Material {
public abstract String toString();
public abstract void doPrinting();
}
아래는 제네릭 클래스 참조 자료형으로 들어갈 클래스 구현 예제이다.
public class Powder extends Material {
@Override
public String toString() {
return "재료는 Powder입니다.";
}
@Override
public void doPrinting() {
System.out.println("Powder 재료로 출력합니다.");
}
}
public class Plastic extends Material {
@Override
public String toString() {
return "재료는 Plastic입니다.";
}
@Override
public void doPrinting() {
System.out.println("Plastic 재료로 출력합니다.");
}
}
아래는 제네릭 클래스의 인스턴스를 생성한 예제이다.
public class ThreeDPrinterTest {
public static void main(String[] args) {
ThreeDPrinter<Powder> printer = new ThreeDPrinter<Powder>();
printer.setMaterial(new Powder());
Powder powder = printer.getMaterial();
System.out.println(powder);
ThreeDPrinter<Plastic> printer2 = new ThreeDPrinter<Plastic>();
printer2.setMaterial(new Plastic());
Plastic plastic = printer2.getMaterial();
System.out.println(plastic);
printer.printing();
printer2.printing();
// ThreeDPrinter<Water> printer3 = new ThreeDPrinter<Water>(); // error
}
}
매개 변수로 참조 자료형을 작성하여 인스턴스를 생성한다. 이때 Material class를 상속받지 않은 참조 자료형을 대입하면 에러가 난다.
아래는 출력 결과이다.