Java 제네릭(Generic) 프로그래밍

Codren·2021년 6월 4일
0
post-custom-banner

Section 1. 제네릭 프로그래밍

1. 제네릭(Generic) 프로그래밍

클래스, 메서드, 인터페이스에서 처리 되는 자료형을 외부에서 지정하는 기법으로써 자료형에 의존적으로 정의하지 않아도 됨

  • 보통 <T / E / K / V> 제네릭 자료형으로 사용
  • 컬렉션 프레임워크에서 많이 사용되고 있음




2. 제네릭 프로그래밍이 필요한 상황

  • 3D 프린터를 구현할 때 재료를 Powder 또는 Plastic 을 사용할 수 있음
  • 재료가 Powder 인 3D 프린터 클래스
public class Powder {
	
	public String toString() {
		return "재료는 Powder 입니다";
	}
}
public class ThreeDPrinter1{
	private Powder material;
	
	public void setMaterial(Powder material) {
		this.material = material;
	}
	
	public Powder getMaterial() {
		return material;
	}

  • 재료가 Plastic 인 3D 프린터 클래스
public class Plastic {

	public String toString() {
		return "재료는 Plastic 입니다";
	}
}
public class ThreeDPrinter2{
	private Plastic material;
	
	public void setMaterial(Plastic material) {
		this.material = material;
	}
	
	public Plastic getMaterial() {
		return material;
	}

}
  • 이렇게 3D프린터 클래스를 각 재료의 자료형마다 생성해줘야함
  • Object 자료형을 이용해도 되지만 매번 다운캐스팅을 구현해야함




3. 제네릭 프로그래밍 구현

  • <> 다이아몬드 연산자를 통해 제네릭 자료형 지정
  • 하나의 3D 프린터 클래스로 Powder 와 Plastic 재료 사용
public class GenericPrinter<T> {		# T 자료형을 처리하는 클래스 
	private T material;   			# T 자료형으로 선언한 변수
	
	public void setMaterial(T material) {	# T 자료형을 매개변수로 받는 제네릭 메서드
		this.material = material;
	}
	
	public T getMaterial() {   		# T 자료형을 반환하는 제네릭 메서드
		return material;
	}
	
	public String toString(){
		return material.toString();
	}
}
# main 부분 
GenericPrinter<Powder> powderPrinter = new GenericPrinter<Powder>();
powderPrinter.setMaterial(new Powder());
GenericPrinter<Plastic> plasticPrinter = new GenericPrinter<Plastic>();
plasticPrinter.setMaterial(new Plastic());




Section 2. T extends 클래스

1. T extends 클래스

제네릭 자료형의 범위를 제한 할 수 있는 기법으로 상속 받는 상위 클래스의 자료형 또는 해당 클래스를 상속 받은 하위 클래스들의 자료형만으로 제한하는 기법




2. T extends 클래스 적용

  • T에 무작위 클래스가 들어갈 수 없게 Material 클래스를 상속받은 클래스로 한정
public class GenericPrinter<T extends Material> {
	private T material;
	
	public void setMaterial(T material) {
		this.material = material;
	}
	
	public T getMaterial() {
		return material;
	}
	
	public String toString(){
		return material.toString();
	}
	
	public void printing() {
		material.doPrinting();
	}
}

  • Material 추상 클래스와 상속 받는 Powder 와 Plastic 클래스

public abstract class Material {
	
	public abstract void doPrinting();
}
public class Powder extends Material{
		
	public void doPrinting() {
		System.out.println("Powder 재료로 출력합니다");
	}
	
	public String toString() {
		return "재료는 Powder 입니다";
	}
}
public class Plastic extends Material{

	public void doPrinting() {
		System.out.println("Plastic 재료로 출력합니다");
	}
	
	public String toString() {
		return "재료는 Plastic 입니다";
	}
}



Section 3. 제네릭 메서드 활용

1. 제네릭(Generic) 메서드

메서드의 반환형 및 매개변수의 자료형과 내부에서 처리되는 자료형을 제네릭 자료형으로 사용하는 메서드




2. 제네릭 메서드 활용

  • 두 점(top, bottom)을 기준으로 사각형을 만들 때 사각형의 너비를 구하는 메서드
public class Point<T, V> {
	
	T x;
	V y;
	
	Point(T x, V y){
		this.x = x;
		this.y = y;
	}
	
	public  T getX() {
			return x;
	}

	public V getY() {
		return y;
    }
}

  • new Point<Integer, Double>(0, 0.0) -> Point<Integer, Double> 형태의 인스턴스 생성
  • p1 은 Point<Integer, Double> 형태의 인스턴스만을 참조할 수 있는 레퍼런스 변수
  • GenericMethod.<Integer, Double>makeRectangle(p1, p2);
    -> Point<Integer, Double> 형태의 인스턴스만을 매개변수(p1,p2)로 받겠다는 의미
public class GenericMethod {

	public static <T, V> double makeRectangle(Point<T, V> p1, Point<T, V> p2) {
		double left = ((Number)p1.getX()).doubleValue();
		double right =((Number)p2.getX()).doubleValue();
		double top = ((Number)p1.getY()).doubleValue();
		double bottom = ((Number)p2.getY()).doubleValue();
		
		double width = right - left;
		double height = bottom - top;
		
		return width * height;
	}
	
	public static void main(String[] args) {
		
		Point<Integer, Double> p1 = new Point<Integer, Double>(0, 0.0);
		Point<Integer, Double> p2 = new Point<>(10, 10.0);
		
		double rect = GenericMethod.<Integer, Double>makeRectangle(p1, p2);
		System.out.println("두 점으로 만들어진 사각형의 넓이는 " + rect + "입니다.");
	}
}
post-custom-banner

0개의 댓글