일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 템플릿
- AOP란?
- SUB Query
- 리스트 모달창
- oracle 연동
- static메서드
- Java
- 사용자 데이터그램 프로토콜
- singleton
- react
- 이클립스 오라클 연동
- static 예제
- order by
- GROUP BY
- 깃 명령어
- 객체협력
- spring annotation
- 오라클 비교연산자
- static
- 추상 메서드
- downcasting
- 형변환
- 상속
- 싱클톤패턴
- 스프링 모달창
- 다중 모달창
- IP
- 모달창 여러개
- Servlet 맵핑
- 다운캐스팅
- Today
- Total
모든지 기록하자!
[Java] 제네릭 (generic) 본문
제네릭이란?
어떤 값이 하나의 참조 자료형이 아닌 여러 참조 자료형을 사용할 수 있도록 프로그래밍하는 것을
제네릭(generic) 프로그래밍이라고 한다. 제네릭 프로그램은 참조 자료형이 변환될 때 검증을 컴파일러가 하기 때문에 안정적이다.
3D 프린터 예제로 제네릭에 대해 알아보자
public class TreeDPrinter{
private Powder material; // 재료가 파우더일 때
public Powder getMaterial() {
return material;
}
public void setMaterial(Powder material) {
this.material = material;
}
플라스틱 액체를 재료로 사용하는 프린터를 구현해 보자
public class TreeDPrinter{
private Plastic material; // 재료가 플라스틱일 때
public Plastic getMaterial() {
return material;
}
public void setMaterial(Plastic material) {
this.material = material;
}
재료만 바뀌고 프린터 기능이 동일하다면 프린터 클래스를 두 개 만드는 것은 비효율적이다.
이런 경우엔 어떤 재료든 쓸 수 있도록 material 변수의 자료형을 Object로 사용 할 수 있다.
Object는 모든 클래스의 최상위 클래스이므로 모든 클래스는 Object로 변환할 수 있다.
Object를 활용하여 만든 코드를 보자
public class TreeDPrinter{
private Object material;
public Object getMaterial() {
return material;
}
public void setMaterial(Object material) {
this.material = material;
}
material 변수의 자료형을 Object로 선언한 ThreeDPrinter에 파우더를 재료로 사용하는 코드를 보자
ThreeDPrinter printer = new TreeDPrinter();
Powder p1 = new Powder();
printer.setMaterial(p1); // 자동 형 변환된다.
Powder p2 = (Powder)printer.getMaterial(); // 직접 형 변환 해야한다.
setMaterial() 메서드를 활용해서 Powder를 재료로 선택할 때는 매개변수 자료형이 Object 이므로 자동으로 형 변환된다. 하지만 반환형이 Object인 getMaterial() 메서드로 Powder 자료형 변수를 반환받을 때는
반드시 형 변환을 해줘야 한다. 어떤 변수가 여러 참조 자료형을 사용할 수 있도록 Object 클래스를 사용하면 다시 원래 자료형으로 반환해 주기 위해 매번 형 변환을 해야 하는 번거로움이 있다.
이러한 경우에 사용하는 프로그래밍 방식이 제네릭이다. 여러 참조 자료형이 쓰일 수 있는 곳에 특정한 자료형을 지정하지 않고, 클래스나 메서드를 정희한 후 사용하는 시점에 어떤 자료형을 사용할 것인지 지정하는 방식이다.
public class GenericPrinter<T>{
private T material;
public T getMaterial() {
return material;
}
public void setMaterial(T material) {
this.material = material;
}
여러 자료형으로 바꾸어 사용할 meterial 변수의 자료형을 T라고 썼다. 이때 사용하는 T를 자료형 매개변수라고 부른다. 클래스 이름을 GenericPrinter <T>라고 정의하고 나중에 클래스를 사용할 때 T 위치에 실제 사용할 자료형을 지정한다. 클래스의 각 메서드에서 해당 자료형이 필요한 부분에는 모두 T문자를 사용해서 구분한다.
제네릭 클래스 사용 예제
public class Powder{
public String toString() {
return "재료는 Powder 입니다.";
}
public void doPrinting() {
System.out.println("Powder 재료로 출력합니다.");
}
public class Plastic{
public String toString() {
return "재료는 Plastic 입니다.";
}
public void doPrinting() {
System.out.println("Plastic 재료로 출력합니다.");
}
}
파우더와 플라스틱 액체를 재료로 모형을 출력하는 프린터를 제네릭 클래스로 정의하면
public class TreeDPrinter<T>{
private T material; // T 자료형으로 선언한 변수
public T getMaterial() { // T 자료형 변수 meterial을 반환하는 제네릭 메서드
return material;
}
public void setMaterial(T material) {
this.material = material;
}
public String toString() {
return material.toString();
}
public class TreeDPrinterTest {
public static void main(String[] args) {
TreeDPrinter<Powder> printer = new TreeDPrinter<Powder>(); // Powder형으로
printer.setMaterial(new Powder()); // ThreeDPrinter 클래스 생성
Powder powder = printer.getMaterial();
System.out.println(printer);
TreeDPrinter<Plastic> printerPlastic = new TreeDPrinter<Plastic>(); // Plastic형으로
printerPlastic.setMaterial(new Plastic()); // ThreeDPrinter 클래스 생성
Plastic plastic = printerPlastic.getMaterial();
System.out.println(printerPlastic);
출력결과
T 자료형에 사용할 자료형을 제한하는 <T extends 클래스>
제네릭 클래스에서 T 자료형에 사용할 자료형에 제한을 두는 방식으로 extends 예약어를 사용할 수 있다.
Material 클래스는 추상 클래스로 정의하였고 상속받은 클래스는 doPrinting() 추상 메서드를 반드시
구현해야 한다.
public abstract class Material {
public abstract void doPrinting();
}
Mererial을 상속받은 Powder와 Plastic 클래스 코드를 보자
public class Plastic extends Material{
public String toString() {
return "재료는 Plastic 입니다.";
}
@Override
public void doPrinting() {
System.out.println("Plastic 재료로 출력합니다.");
}
}
public class Powder extends Material{
public String toString() {
return "재료는 Powder 입니다.";
}
@Override
public void doPrinting() {
System.out.println("Powder 재료로 출력합니다.");
}
public class TreeDPrinter<T extends Material>{
// extends 예약어로 사용할 수 있는 자료형에 제한을 둔다.
private T material;
...(생략)
}
<T extends 클래스>로 상위 클래스 메서드 사용하기
<T extends Material>로 선언하면 제네릭 클래스를 사용할 때 상위 클래스 Material에서 선언한 메서드
toPrinting()을 사용할 수 있다. <T extends Material>을 사용 하지않으면 T는 컴파일 할 때 Object 클래스로 변환된다. 이 경우에 Object 클래스가 기본으로 제공하는 메서드만 사용할수 있다. 자료형을 알 수 없기
때문이다.
'Java' 카테고리의 다른 글
[Java] 디자인패턴 ( singleton, factory) 예제 (0) | 2021.05.24 |
---|---|
[Java] 컬렉션 프레임워크 (collection framework) (0) | 2021.05.21 |
[Java] 인터페이스 요소 (0) | 2021.05.19 |
[Java] 인터페이스 ( interface) ( 예제: 상담원 배분) (0) | 2021.05.18 |
[Java] 템플릿(template) 메서드 , final 예약어 (예제 : Player) (0) | 2021.05.18 |