[Java] Generic Programming (제너릭 프로그래밍)

SeongWon Oh·2021년 8월 19일
0

Java

목록 보기
22/39
post-thumbnail

Generic class / Programming

  • 프로그래밍을 하다보면 여러 자료형이 쓰일 수 있는 변수가 존재할 경우 이 변수를 기반으로 클래스를 만들어야 할 것이다. 이런 경우 비슷한 코드를 자료형에 따라 여러개의 클래스를 만들게 된다면 overhead가 발생할 것이다.

  • 우리는 이러한 상황이 발생하는 경우 여러 자료형을 담을 수 있는 Generic class을 사용하며 프로그래밍을 하여야한다.

  • Generic class은 자료형을 특정하지 않고 추후 해당 클래스를 사용할 때 지정 할 수 있도록 선언하는 방법을 사용한다.

  • 이러한 Generic class을 사용하여 다양한 자료형이 적용될 수 있는 class나 method를 만드는 것을 generic programming이라고 한다.

  • Generic class은 자바 5.0부터 제공이 되었다.

  • Collection Framework에서 많이 사용되고 있다.

즉, 자료형을 특정하지 않아 사용을 할 때 원하는 자료형을 선언하여 사용하게 해주는 변수를 generic class이라고 하며 해당 변수를 사용하는 프로그래밍을 Generic Programming이라고 한다.

Generic class사용법

  • Generic class 생성
    • Generic class를 사용할 경우 아래의 코드와 같이 Class명 옆에 < T >를 입력하여야한다.
	public class GenericPrinter<T>
  • Generic variable 생성
    • T는 자료형 매개변수로 이 클래스를 사용하는 시점에 실제 사용할 자료형으로 지정하여 사용한다.
    • static 변수는 사용할 수 없다
	private T material;
  • Generic method
    • 하나 이상의 자료형 매개 변수를 입력받고 반환하는 매서드이다.
    • generic class가 아니어도 generic method를 구현하여 사용할 수 있다.
    • public <자료형 매개 변수> 반환형 메서드 이름(자료형 매개변수.....) { }
    • 아래의 코드와 같이 return값이 있는 method면 자료형 위치에 T를 적어둔며, parameter를 받아야 하는 경우도 해당 위치에 T를 적어둔다.
	public T getMaterial() {
		return material;
	}

	public void setMaterial(T material) {
		this.material = material;
	}
  • 정의한 Genric class를 생성
    • <>안에 사용하고자 하는 자료형을 입력해주면 된다.
    • <>를 생략하게 되면 해당 인스턴스는 Object로 생성된다.
	GenericPrinter<Powder> powderPrinter = new GenericPrinter<>();

Generic class을 사용하지 않는 경우

👨🏻‍💻 Example Code

Powder.java

package ch06;

public class Powder {
	public String toString() {
		return  "재료는 powder입니다. ";
	}
}

ThreeDPrinter1.java

package ch06;

public class ThreeDPrinter1 {
	private Powder material;

	public Powder getMaterial() {
		return material;
	}

	public void setMaterial(Powder material) {
		this.material = material;
	}
	
	public String toString() {
		return "재료는 Powderrf 입니다.";
	}
}

위의 Powder class와 비슷한 다른 객체를 생성하는 경우 TheeDPrinter코드도 해당 class가 생성됨에 따라 따로 만들어져야 할 것이다. 또는 아래 코드와 같이 Object를 사용하여 코딩할 수도 있다. 하지만 Object의 경우 인스턴스를 생성하고 사용을 할 때 형변환을 해줘야하는 번거로움이 발생한다.

ThreeDPrinter3.java

package ch06;

public class ThreeDPrinter3 {
	private Object material;

	public Object getMaterial() {
		return material;
	}

	public void setMaterial(Object material) {
		this.material = material;
	}
	
	public String toString() {
		return "재료는 Powderrf 입니다.";
	}
}

ThreeDPrinterTest.java

package ch06;

public class ThreeDPrinterTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Powder powder = new Powder();
		ThreeDPrinter3 printer = new ThreeDPrinter3();
		
		printer.setMaterial(powder);
		Powder p = (Powder)printer.getMaterial();
		// ThreeDPrinter3의 경우는 Object type을 이용하여 material을 만들었는데
		// 이럴 경우 형 변환을 해줘야해서 번거로움이 발생한다.
		// 그래서 generic programming이 생겨났다.
		
	}
}

Generic class를 사용한 코드

👨🏻‍💻 Example Code

GenericPrinter.java

package ch06;

public class GenericPrinter<T> {
	// T는 자료형 매개변수로 이 클래스를 사용하는 시점에 실제 사용할 자료형을 지정하며 static 변수는 사용할 수 없다
	
	private T material;
	// 나중에 사용할 때 사용할 자료형을 입력하면 해당 자료형으로 생성된다.

	public T getMaterial() {
		return material;
	}

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

GenericPrinterTest.java

package ch06;

public class ThreeDPrinterTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Powder powder = new Powder();
		ThreeDPrinter3 printer = new ThreeDPrinter3();
		
		printer.setMaterial(powder);
		Powder p = (Powder)printer.getMaterial();
		// ThreeDPrinter3의 경우는 Object type을 이용하여 material을 만들었는데
		// 이럴 경우 형 변환을 해줘야해서 번거로움이 발생한다.
		// 그래서 generic programming이 생겨났다.
		
	}

}

※ 그 외 코드는 위와 중복되어 생략

T 자료형의 범위 제한

  • <T extends 클래스>를 사용하면 T 자료형의 범위를 제한할 수 있다.

  • Generic class에 상위 클래스 상속을 할 경우 T에는 상속을 받은 Class(자료형)으로만 생성 가능하다.

  • 상속을 받지 않는 경우 T는 Object로 변환되어 Object 클래스가 기본으로 제공하는 메서드만 사용가능하다.

  • extends를 사용함으로써 사용할 수 있는 class에 대하여 제한을 걸어두고 공통으로 사용하는 method들을 지정해줄 수 도 있다.

👨🏻‍💻 Example Code

Material.java

package ch07;

//Generic class의 제한을 걸기 위한 class로 
//해당 class는 직접 쓸 일이 없기에 abstract로 생성하였다.
public abstract class Material {
	public abstract void doPrinting();
}

Plastic

package ch07;

public class Plastic extends Material {
	public String toString() {
		return  "재료는 plastic 입니다. ";
	}

	@Override
	public void doPrinting() {
		// TODO Auto-generated method stub
		
	}	
}

GenericPrinter

package ch07;

public class GenericPrinter<T extends Material> {
	// extends Material을 하여 T에 대한 제한을 하였다.
	// Material을 상속받은 Class(자료형)으로만 생성 가능하다!!
	
	private T material;
	// 나중에 사용할 때 사용할 자료형을 입력하면 해당 자료형으로 생성된다.

	public T getMaterial() {
		return material;
	}

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

※ 그 외 코드는 위와 중복되어 생략


Reference

  • [Fast Campas] 한번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online.
profile
블로그 이전했습니다. -> https://seongwon.dev/

0개의 댓글