JAVA/컬렉션 프레임워크

04. < T extends 클래스 > 자료형매게변수 제한하기

김꾸꾸(하트) 2022. 11. 22. 22:27

< T extends 클래스 >

사용하는 이유는?

제네릭 클래스에서 T자료형에 사용할 클래스를 제한하기 위해서 사용.( 아무 클래스나 사용불가 )

ex) 만약 Food클래스가 있는 데 food클래스의 material 변수의 자료형으로 Poison이 들어간다면 안되겠쥬..?

아무래도 음식의 재료가 독이면 사람은 죽으니까..

GenericFood<Poison> food = new GenericFood<Poison>();

 

제네릭 클래스에서 자료형매게변수를 제한하는 법

   1.    제한 기준을 추상 클래스로 정의하기 (ex. Material (재료 [멭털리아]) )

   2.   사용해야할 여러 참조자료형이 해당 추상클래스 상속받기

   3.   < T extends 추상클래스 >로 제한 두기자료형 매게변수가 제한 기준이 되는 클래스를 상속받기

 

why추상클래스?

내 생각에는 제한 기준이 되는 클래스가 상속받는 클래스들에게

반드시 재정의해야하는 공통된 메서드를 제공하기 위해서인 것 같다

 

 

 

특징

  1. 제네릭클래스의 자료형매개변수가 상속받은 클래스상속 받지 않은 클래스를 사용하면 오류걸림
  2. 제네릭클래스의 자료형매개변수가 상속받은 클래스메서드 사용가능

 

 

예제

제한 기준을 클래스로 정의하기

Material 추상클래스 정의하기( 특정 클래스 )

//(*)제네릭클래스에서 제한하는 데 기준이 되는 것을 추상클래스로 정의하기
public abstract class Material { // ThreeDPrint에서는 재료가 기준이라 Material로 추상클래스 정의함.
	
	public abstract void doPrinting(); // 상속받는 모든 클래스가 구현해야하는 추상메서드
	
	

}

 

 

 

 

 

재료

Powder클래스 정의하기

// Material클래스를 상속받음
public class Powder extends Material {

	@Override
	public void doPrinting() {
		System.out.println("Powder 재료로 출력합니다.");
	}

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

	
	
}

 

Plastic클래스 정의하기

// Material클래스를 상속받음
public class Plastic  extends Material{

	@Override
	public void doPrinting() {
		System.out.println("Plastic 재료로 출력합니다.");
	}

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

}

 

Water클래스 정의하기( Material클래스를 상속받지 않음 )

//물이 TreeDPrinter의 재료가 된다면 정상작동 하지 않을 것이기 때문에 Material클래스를 상속하지 않음.
public class Water { 
	
	public void doPrinting() {
		System.out.println("Water를 재료로 출력합니다.");
	}

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

 

 

 

 

제네릭 클래스 정의

GenericPrinter< T extends Material > 정의하기

//< T extends 클래스>를 사용해서 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();
		}
		
		
		// Material클래스의 doPrinting메서드를 호출함
		public void printing() {
			material.doPrinting();
		}

		

}

 

 

 

 

 

실행하기

GenericPrinterTest

public class GenericPrinterTest {
	public static void main(String[] args) {

		GenericPrinter<Powder> powderPrinter = new GenericPrinter<>(); 
		powderPrinter.setMaterial( new Powder() );
		powderPrinter.printing();
		
		GenericPrinter<Plastic> plasticPrinter = new GenericPrinter<>();
		plasticPrinter.setMaterial( new Plastic() );
		plasticPrinter.printing();
		
		
		// 자료형 매게변수로 Material를 상속 받지 않은 Water클래스를 넣으면 오류 걸림.
		// GenericPrinter<Water> WaterPrinter = new GenericPrinter<>();
		
		
		
		
		
		
		
	}
}

 

 

 

 

 

 

 

 

 

출처 - Do it! 자바 프로그래밍 입문 (박은종 선생님) 

https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=157852460 

 

Do it! 자바 프로그래밍 입문

개발 실무 10년, 강의 10년, 자바 장인이 왕초보 학생들과 부대끼며 깨달은 눈높이로 자바 학습 노하우를 공개한다. 중학교 1학년도 쉽게 이해할 수 있을 만큼 쉬운 말로 풀어서 설명했으며, 저자

www.aladin.co.kr