⭐제네릭 프로그래밍
Generic Programming
타입을 일반화하여
재사용 가능한 코드를 작성하도록 하는 기법이다.
👍특히 데이터 타입이 다르지만
변수명을 동일하게 사용해야 한다면
제네릭 프로그래밍을 활용할 수 있다.
🤔Why?
타입의 안정성
코드의 재사용성
유지보수성
😎How?
클래스, 데이터타입, 메서드 등에서
<T> 같은 형태의 대체 문자열을 선언하면 된다.
T(ype) E(lement), K(ey), V(alue).. 아무 문자나 넣어도 상관없다.
이를 자료형 매개변수 (Type parameter) 라고 한다.
제네릭을 쓴 클래스는
사용하는 시점에 실제 사용될 자료형이 결정된다.
💀제네릭 프로그래밍의 문제점
개발자가 의도하지 않게 엉뚱한 클래스까지 들어올 가능성이 있다.
✨T extends 클래스
T 자료형의 범위를 제한한다.
예제1.
GenericPrinter 클래스, 이와 상호작용해는 재료클래스인 Plastic, Powder, Water 를 만들었다.
원래는 재료를 바꿀 때마다 새로운 클래스를 생성하거나 코드를 수정해야 하는 번거로움이 있다.
하지만 제네릭 프로그래밍을 해주면
형변환이 필요없고 좀 더 편하게 쓸 수 있다.
또한 컴파일 시점에 오류를 알려줘
안정적 코드작업을 돕는다.
package _generic.ch02;
/**
5.8
제네릭 프로그래밍을 사용해본다.
클래스, 데이터타입, 메서드 등에서
<T> 대체 문자열을 선언할 수 있다.
*/
public class GenericPrinter<T> {
/*
T(ype) 라는 대체 문자를 사용한다.
E(lement), K(ey), V(alue).. 아무 문자나 넣어도 상관없다.
이를 자료형 매개변수 (Type parameter) 라고 한다.
제네릭을 쓴 클래스는
사용하는 시점에 실제 사용될 자료형이 결정된다.
*/
T material; // T 대체 문자형으로 변수를 선언할 수 있다.
// get,set
public T getMaterial() {
return material;
}
public void setMaterial(T material) {
this.material = material;
}
//method
@Override
public String toString() {
return material.toString();
}
}//class
1-2. 재료클래스
package _generic.ch02;
public class Plastic {
@Override
public String toString() {
return "재료는 플라스틱 입니다.";
}
}//Plastic
package _generic.ch02;
public class Powder {
@Override
public String toString() {
return "재료는 파우더 입니다.";
}
}//Powder
package _generic.ch02;
public class Water {
@Override
public String toString() {
return "재료는 물 입니다.";
}
}//Water
1-3. 코드 테스트부
package _generic.ch02;
public class MainTest2 {
public static void main(String[] args) {
//재료 선언
Plastic plastic1 = new Plastic();
Powder powder1 = new Powder();
//사용하는 시점에 T 대신 어떤 자료형을 사용할 지 지정해준다.
GenericPrinter<Plastic> gPrinter1 = new GenericPrinter<>();
gPrinter1.setMaterial(plastic1);
System.out.println(gPrinter1.toString()); // "재료는 플라스틱 입니다."
//재료꺼내기
Plastic usePlastic = gPrinter1.getMaterial(); //형변환이 필요없다
/*
제네릭으로 만들면
형변환이 필요없고
좀 더 편하게 쓸 수 있다.
또한 컴파일 시점에 오류를 알려줘
안정적 코드작업을 돕는다.
*/
// Powder usePowder = gPrinter1.getMaterial();
Water water1 = new Water();
GenericPrinter<Water> gPrinter2 = new GenericPrinter<>();
gPrinter2.setMaterial(water1);
System.out.println(gPrinter2.toString()); // "재료는 물 입니다."
}//main
}//class
예제2.
의도치않게..
물 같은 의도하지 않은 재료가 들어오는 것을 막으려면
<T extends Object> 구문을 활용하면 된다.
여기서는 Material 을 상속받은 재료 클래스만 대체 문자열에 들어올 수 있도록 해봤다.
package _generic.ch03;
/**
5.8
제네릭 프로그래밍을 사용하자
<T> 다음은 <T extends Object>
Material 을 상속받은 자식 클래스만
대체 문자열에 들어올 수 있다.
*/
public class GenericPrinter<T extends Material> {
//member
T material;
//get set
public T getMaterial() {
return material;
}
public void setMaterial(T material) {
this.material = material;
}
//method
@Override
public String toString() {
return material.toString();
}
}//class
2-1. 추상클래스 Material과 재료(자식)클래스들 설계
package _generic.ch03;
public abstract class Material {
public abstract void doPrining(); //추상메서드
}//class
package _generic.ch03;
public class Plastic extends Material {
@Override
public String toString() {
return "재료는 플라스틱 입니다.";
}
@Override
public void doPrining() {
System.out.println("플라스틱을 사용해서 프린팅..");
}
}//Plastic
package _generic.ch03;
public class Powder extends Material {
@Override
public String toString() {
return "재료는 파우더 입니다.";
}
@Override
public void doPrining() {
System.out.println("파우더를 사용해서 프린팅..");
}
}//Powder
2-1-2.
상속 받지 못한 Water 클래스
package _generic.ch03;
public class Water {
@Override
public String toString() {
return "재료는 물 입니다.";
}
}
2-2. 코드 테스트
제네릭 프로그래밍을 하면 타입의 안정성을 확보하고
<T extends Object> 같은 기능을 통해 타입에 제한을 둘 수도 있다.
package _generic.ch03;
public class MainTest3 {
public static void main(String[] args) {
//재료 선언
Powder powder1 = new Powder();
Plastic plastic1 = new Plastic();
Water water1 = new Water();
GenericPrinter<Powder> gPinter1 = new GenericPrinter<>();
gPinter1.setMaterial(powder1);
/*
제네릭 프로그래밍을 하면
타입의 안정성과
T extends Object
타입에 제한을 둘 수 있다.
*/
//Water를 사용해보자 - 컴파일 시점 오류 발생
// GenericPrinter<Water> gPrinter2 = new GenericPrinter<Water>();
}//main
}//class
예제3.
제네릭 클래스 설계하고 활용
package _generic.ch04;
/**
5.8
제네릭 클래스 Box 설계
*/
public class Box<T> {
//변수
T material;
//생성자
public Box(T material) {
this.material = material;
}
//get set
public T getMaterial() {
return material;
}
public void setMaterial(T material) {
this.material = material;
}
//출력
@Override
public String toString() {
return material.toString();
}
}
3-1.
코드실행부
package _generic.ch04;
/**
5.8
제네릭 클래스 Box 설계
*/
public class GenericBoxDemo {
public static void main(String[] args) {
//String 타입 Box 선언 및 사용
Box<String> stringBox = new Box<>("문자열");
System.out.println(stringBox.toString());
stringBox.setMaterial("변경된 문자열");
System.out.println(stringBox.toString());
//Integer 타입 Box 선언 및 사용
Box<Integer> integerBox = new Box<>(1234);
System.out.println(integerBox.toString());
integerBox.setMaterial(4321);
System.out.println(integerBox.toString());
//Double 타입 박스 선언 및 사용
Box<Double> doubleBox = new Box<>(0.1234);
System.out.println(doubleBox.getMaterial());
doubleBox.setMaterial(0.4321);
doubleBox.toString();
}//main
}//class
'Java' 카테고리의 다른 글
JDBC, 자바와 SQL 징검다리 (0) | 2025.05.12 |
---|---|
[인텔리제이] lombok, JDBC 라이브러리 추가 방법 (0) | 2025.05.12 |
Java자바 Swing 예제. 플래포머 게임 만들기 4.천장구현 (0) | 2025.05.08 |
컬렉션 프레임워크 3. Map 키값과 밸류값이 '한쌍' (1) | 2025.05.07 |
컬렉션 프레임워크 2. Set 중복방지용 '주머니' (0) | 2025.05.07 |