- 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미
- 어떤 값이 하나의 참조 자료형이 아니니 여러 참조 자료형을 사용할 수 있도록 프로그래밍하는 것을
제네릭 프로그래밍
이라고 한다💡 즉, 클래스를 정의 할 때는 데이터 타입을 확정하지 않고 인스턴스를 생성할 때 데이터 타입을 지정하는 기능이 제네릭이다.
하나의 예시를 들어서 알아보자 !
3D프린터를 예로 들어보면,
3D 프린터는 재료를 가지고 입체 모형을 만드는일을 한다.
프린터에 쓰이는 재료는 여러가지가 있을 수 있는데, 쌓아 올려 입체 모형을 만드는 경우에
파우더
나 플라스틱 액체
를 사용한다.
그러면 다음과 같이 파우더
를 재료로 사용하는 3D 프린터 클래스 코드를 먼저 만들어 보자
💡 파우더를 재료로 사용하는 3D 프린터 클래스 💡
public class ThreeDprinter {
// 재료가 파우더인 경우
private Powder material;
public void setMaterial (Powder material) {
this.material = material;
}
public Powder getMaterial() {
return material;
}
} ////////////////////////// class
플라스틱 액체
일 경우는 또 클래스를 만들어야 하는지 의문이 든다일단 재료가 플라스틱 액체
일 경우의 클래스도 만들어보자 !
💡 재료가 플라스틱 액체일 경우의 클래스 💡
public class ThreeDprinter {
// 재료가 플라스틱 액체인 경우
private Plastic material;
public void setMaterial (Plastic material) {
this.material = material;
}
public Plastic getMaterial() {
return material;
}
} ////////////////////////// class
재료만 다를 뿐인데 굳이 두개의 클래스를 만들 필요가 있을까?
💡 Object 를 활용한 제네릭 프로그래밍 💡
public class ThreeDprinter {
// 모든 타입을 Object로 선언
private Object material;
public void setMaterial (Object material) {
this.material = material;
}
public Object getMaterial() {
return material;
}
} ////////////////////////// class
그러면 Object로 선언한 ThreeDPrinter에 파우더를 재료로 사용할 경우 코드를 입력해보자!
💡 Object로 선언한 ThreeDPrinter에 파우더를 재료로 사용할 경우 💡
ThreeDPrinter printer = new ThreeDPrinter();
Powder p1 = new Powder();
printer.setMaterial(p1); // 자동으로 형 변환이 된다.
Powder p2 = (Powder)printer.getMaterial(); // 직접 형 변환을 해야된다.
제네릭 방식
이라고 한다.Object
가 아닌 하나의 문자로 표현한다.위에서 예를 든 ThreeDPrinter
을 제네릭
클래스로 정의해보자
💡 제네릭 클래스 정의하기 💡
public class GenericPrinter<T> {
private T material;
public void setMaterial(T material) {
this.material = material;
}
public T getmaterial() {
return material;
}
}/////////////////// class
T
는 type
의 약자로 자료형 매개변수
라고 부른다.T
위치에 실제 사용할 자료형을 지정하면 된다.E
는 element
K
는 key
V
는 value
의미가 이렇다는것이지 꼭 이런 문자를 사용해야 하는것은 아니다.
<T extends 클래스>
아래에서 예시를 통해 알아보자!
💡 자료형을 제한하는 <T extends 클래스> 💡
public class GenericPrinter<T extends Material> {
private T material;
}
Powder
와 Plastic
클래스가 Material
을 상속 받는다고 했을 경우 <T extends Material>
이라고 명시하여 사용할 수 있는 자료형에 제한을 둘 수 있다.Materil
클래스를 상속받지 않은 Water
클래스를 사용하면 오류가 발생할 것이다.그동안 우리가 많이 사용한 ArrayList를 살펴보자!
💡 다이아몬드 연산자<> 💡
ArrayList<String> list = new ArrayList<>();
<>
를 다이아몬드 연산자 라고 한다String
임을 컴파일러가 유추할 수 있기 때문에 생성 부분에서는 생략이 가능하다.