JAVA 유용한 클래스

(JAVA)제네릭(Generic) -9

mynote6676 2025. 5. 8. 17:19

제네릭 프로그래밍은 자바에서 타입을 일반화하여 재사용 가능한 코드를 작성하는 기법입니다. 제네릭을 사용하면 클래스,

인테페이스, 메서드 등에 대해 특정 타입을 지정하지 않고, 다양한 타입에서 동작하도록 할 수 있습니다.

 

데이터 타입은 다르지만 변수명을 동일하게 사용해야 된다면 제네릭 프로그래밍을 활용할 수 있다.

 

제네릭 프로그래밍의 주요 이점

1. 타입 안정성: 컴파일 시 타입을 검사하여 런타임 에러를 줄일 수 있습니다.

2. 코드의 재사용성: 다양한 타입을 처리할 수 있는 일반화된 코드를 작성할 수 있습니다.

3. 유지보수성 : 타입 캐스팅을 줄여 가독성 유지보수성을 향상시킵니다.

 

시나리오 코드 1단계

더보기
package generic;

public class Plastic {

    @Override
    public String toString() {
        return "재료는 플라스틱입니다";
    }
} // end of class

 

package generic;

public class Powder {
    @Override
    public String toString() {
        return "재료는 파우더입니다";
    }
} // end of class

 

package generic;

public class ThreeDPrinter1 {

    //재료 선언
    Plastic material;

    //get,set
    public Plastic getMaterial(){
        return material;
    }

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

} // end of class

 

package generic;

public class ThreeDPrinter2 {

    Powder material;

    //get,set
    public Powder getMaterial(){
        return material;
    }

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


}//end of class

 

package generic;

public class ThreeDPrinter3 {

    Object meterial;

    public Object getMeterial(){
        return meterial;
    }
    public void setMeterial(Object meterial){
        this.meterial = meterial;
    }

}

 

package generic;

public class MainTest1 {

    public static void main(String[] args) {

        Plastic plastic1 = new Plastic();
        Powder powder1 = new Powder();

        ThreeDPrinter1 dPrinter1 = new ThreeDPrinter1();
        //재료를 주입 해주어야한다.
        dPrinter1.setMaterial(plastic1);

        // 위 코드의 한계는 재료가 플라스틱에서 파우더로 변경해야 한다면
        // 재료가 플라스틱에 종속되어 있기 때문에 ThreeDPrinter2처럼
        //클래스를 생성하거나 코드를 수정해야하는 번거로움 발생한다.
        ThreeDPrinter2 threeDPrinter2 = new ThreeDPrinter2();
        threeDPrinter2.setMaterial(powder1);


    }// end of main

}// end of class

 

 

시나리오 코드 2단계

 
 
 
 

 

더보기

 

 

package generic.ch02;

public class Water {

    @Override
    public String toString() {
        return "재료는 물입니다";
    }
}
package generic.ch02;

/**
 * 제네릭 프로그래밍을 사용해 보자.
 * 문법 클래스, 변수, 데이터 타입, 메서드 등에서 <T>대체 문자열을 선언할 수 있다.
 */
public class GenericPrinter<T> {

    // T(type)라는 대체 문자를 사용, E(element), K(key), V(value) (사실 아무 문자나 사용 가능하다.)
    // 자료형 매개변수 (type parameter)
    // 이 클래스는 사용하는 시점에 실제 사용될 자료형이 결정이 된다.

    T material; // T 대체 문자형으로 변수를 선언할 수 있다.

    //get,set
    public T getMaterial() {
        return material;
    }

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

    @Override
    public String toString() {
        return material.toString();
    }
} // end of class



시나리오코드 3 단계

더보기

<T extends 클래스 > 사용하기

 

상위 클래스의 필요성 - (물이라는 재료를 넣어서 마구 활요하는것을 막을 수 있다.)

 

-T자료형의 범위를 제한 할 수 있음

-상위 클래스에서 선언하거나 정의하는 메서드를 활용할 수 있음

 

 

package generic.ch03;

/**
 * 제네릭 프로그래밍을 사용하자<T>  ---> 다음단계 < T extends Object>
 *     Meterial 를 상속받은 자식 클래스만 대체 문자열에 들어올 수 있다.
 */
public class GenericPrinter <T extends Meterial> {

    T material;

    //get,set
    public T getMaterial(){
        return material;
    }

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

    public String toString(){
        return material.toString();
    }
}
package generic.ch03;

/**
 * 추상적 개념이라 사용하는 개발자에게 마음대로 new 못하게 설계
 */
public abstract class Meterial {
    // 추상클래스란? - 단하나의 추상 메서드를 포함한다면 그 클래스는 추상 클래스이어야 한다.
    public abstract void doPrinting();

}
package generic.ch03;

public class Plastic extends Meterial {

    @Override
    public String toString() {
        return "재료는 플라스틱입니다";
    }

    @Override
    public void doPrinting() {
        System.out.println("플라스틱으로 프린팅....");
    }
} // end of class

 

package generic.ch03;

public class Powder extends Meterial {
    @Override
    public String toString() {
        return "재료는 파우더입니다";
    }


    @Override
    public void doPrinting() {
        System.out.println(" 파우더를 사용해서 프린팅.....");
    }
} // end of class

 

package generic.ch03;

public class Water {

    @Override
    public String toString() {
        return "재료는 물입니다";
    }
}

 

package generic.ch03;

import generic.ch02.Plastic;
import generic.ch02.Water;

public class MainTest3 {

    public static void main(String[] args) {

        //재료 선언
        Powder powder1 = new Powder();
        Plastic plastic1 = new Plastic();
        Water water1 = new Water();

        // 타입에 안정성과 < T extends Object> 타입에 제한을 둘 수 있다.
      GenericPrinter<Powder> genericPrinter1 = new GenericPrinter<>();
      genericPrinter1.setMaterial(powder1);


      //Water 를 사용해보자.
        //컴파일 시점오류 발생
        //GenericPrinter<Water> genericPrinter2 = new GenericPrinter<Water>();


    } // end of main
}

 

도전 과제

더보기
package generic.ch04;

/**
 * 도전 과제
 * 제네릭 클래스 Box 설계<T>대체 문자열을 설계해보자
 */
public class Box <T>{

    //변수 선언
    T item;

    //생성자 선언
    public Box(T item){
        this.item= item;
    }

    //내용물  설정(set 메서드)

    public void setItem(T item) {
        this.item = item;
    }

    //내용물 반환(get 메서드)

    public T getItem() {
        return item;
    }


    //내용물 출력(sout..)

    @Override
    public String toString() {
        return "??입니다.";
    }
}

 

package generic.ch04;

public class GenericBoxDemo{

    public static void main(String[] args) {
        // String 타입에 Box 선언 및 사용.
        Box<String> stringBox =new Box<>("box");


        // Integer 타입에 Box 선언 및 사용
        Box<Integer> integerBox = new Box<>(100);

        // double --> 래퍼클래스 ---> Double 타입에 Box 선언 및 사용
        Box<Double> doubleBox = new Box<>(2.3);
    }
}