자료형이 여러개
일수 있고, 그 기능(메서드)
은 동일한 경우 클래스의 자료형을 특정하지 않고 추후 해당 클래스를 사용할 때 지정
할 수 있도록 선언제네릭 타입을 사용하지 않는 경우의 예
public class ThreeDPrinter1{
private Powder material;
public void setMaterial(Powder material) {
this.material = material;
}
public Powder getMaterial() {
return material;
}
}
public class ThreeDPrinter2{
private Plastic material;
public void setMaterial(Plastic material) {
this.material = material;
}
public Plastic getMaterial() {
return material;
}
}
만드는 방식은 같으나 재료가 다른경우 각각 클래스를 만들어야 될 경우 생김
public class ThreeDPrinter{
private Object material;
public void setMaterial(Object material) {
this.material = material;
}
public Object getMaterial() {
return material;
}
}
ThreeDPrinter printer = new ThreeDPrinter();
Powder powder = new Powder();
printer.setMaterial(powder);
Powder p = (Powder)printer.getMaterial();
여러 타입을 대체하기 위해 Object 사용시 나중에 클래스의 형 변환을 해주어야 함
// 나중에 쓸때 <T>에 실제로 사용할 자료형 입력해주면 됨!
public class GenericPrinter<T> {
private T material;
public void setMaterial(T material) {
this.material = material;
}
public T getMaterial() {
return material;
}
public String toString(){
return material.toString();
}
}
public class GeneriPrinterTest {
public static void main(String[] args) {
// <> 안에 자료형 생략 시 Object형이라고 추론
// 위 경우 사용시 형변환이 필요!
GenericPrinter<Powder> powderPrinter = new GenericPrinter<Powder>();
powderPrinter.setMaterial(new Powder());
System.out.println(powderPrinter);
GenericPrinter<Plastic> plasticPrinter = new GenericPrinter<Plastic>();
plasticPrinter.setMaterial(new Plastic());
System.out.println(plasticPrinter);
}
}
상속을 받지 않는 경우 T는 Object
로 변환되어 Object 클래스가 기본으로 제공하는 메서드만 사용가능
GenericPrinter 에 material 변수의 자료형을 상속받아 구현
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 입니다";
}
}
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();
}
}
public class GenericPrinterTest {
public static void main(String[] args) {
GenericPrinter<Powder> powderPrinter = new GenericPrinter<Powder>();
powderPrinter.setMaterial(new Powder());
Powder powder = powderPrinter.getMaterial(); // 형변환 하지 않음
System.out.println(powderPrinter);
GenericPrinter<Plastic> plasticPrinter = new GenericPrinter<Plastic>();
plasticPrinter.setMaterial(new Plastic());
Plastic plastic = plasticPrinter.getMaterial(); // 형변환 하지 않음
System.out.println(plasticPrinter);
// 자료형 추론 경우
GenericPrinter powderPrinter2 = new GenericPrinter();
powderPrinter2.setMaterial(new Powder());
Powder powder = (Powder)powderPrinter.getMaterial();
System.out.println(powderPrinter);
// Water라는 클래스는 material 상속 X -> 자료형으로 사용 X
//GenericPrinter<Water> printer = new GenericPrinter<Water>();
}
}
public <자료형 매개 변수> 반환형 메서드 이름(자료형 매개변수.....) { }
package ch07;
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;
}
}
package ch07;
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<Integer, Double>(10, 10.0);
double size = GenericMethod.<Integer, Double>makeRectangle(p1,p2);
System.out.println(size);
}
}