Java #7

황현근·2023년 5월 4일
0

Acorn-Academy

목록 보기
17/28
post-thumbnail

제네릭 클래스(Generics Class)

  • 자바에서 제네릭(Generics)은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. 객체별로 다른 타입의 자료가 저장될 수 있도록 한다.
ArrayList<String> list = new ArrayList<>();
  • 이처럼 제네릭은 배열의 타입을 지정하듯이 리스트 자료형 같은 컬렉션 클래스나 메소드에서 사용할 내부 데이터 타입(type)파라미터(parameter) 주듯이 외부에서 지정하는 이른바 타입을 변수화 한 기능이라고 이해하면 된다.

제네릭 타입 매개변수

  • 제네릭은 < > 꺾쇠 괄호 키워드를 사용하는데 이를 다이아몬드 연산자라고 한다. 그리고 이 꺾쇠 괄호 안에 식별자 기호를 지정함으로써 파라미터화 할 수 있다. 이것을 마치 메소드가 매개변수를 받아 사용하는 것과 비슷하여 제네릭의 타입 매개변수(parameter) / 타입 변수라고 부른다.
List<t>  //--- 타입 매개변수
List<String> stringList = new ArrayList<String> ( );
  • 이 타입 매개변수는 제네릭을 이용한 클래스나 메소드를 설계할 때 사용된다.
  • 타입 파라미터 생략
    • 제네릭 객체를 사용하는 문법 형태를 보면 양쪽 두 군데에 꺾쇠 괄호 제네릭 타입을 지정함을 볼 수 있다. 하지만 맨 앞에서 클래스명과 함께 타입을 지정해 주었는데 굳이 생성자까지 제네릭을 지정해 줄 필요가 없다. (중복)
FruitBox<Apple> intBox = new FruitBox<Apple>();

// 다음과 같이 new 생성자 부분의 제네릭의 타입 매개변수는 생략할 수 있다.
FruitBox<Apple> intBox = new FruitBox<>();
  • 제네릭에서 할당 받을 수 있는 타입은 Reference 타입 뿐이다. 즉, int형 이나 double형 같은 자바 원시 타입(Primitive Type)을 제네릭 타입 파라미터로 넘길 수 없다는 말이다.
// 기본 타입 int는 사용 불가 !!!
List<int> intList = new List<>(); 

// Wrapper 클래스로 넘겨주어야 한다. (내부에서 자동으로 언박싱되어 원시 타입으로 이용)
List<Integer> integerList = new List<>();


사용 예시

//가상의 과일 박스
public class FruitBox<T> {

	//필드
	private T item;

	//과일을 포장하는 메소드
	public void pack(T item) {
		this.item = item;
	}

	//과일을 리턴하는 메소드
	public T unPack() {
		return item;
	}
}
---------------------------------------------------------------------------
package test.mypac;

public class Apple {

}
----------------------------------------------------------------------------
public class Melon {

}
----------------------------------------------------------------------------
public class Orange {

}
---------------------------------------------------------------------------
package test.main;

import test.mypac.*;

public class MainCLass {
	@SuppressWarnings("unused")
	public static void main(String[] args) {
	//FruitBox 객체를 생성해서 참조값을 box라는 이름의 지역 변수에 담아보세요
		FruitBox<Apple> box =new FruitBox<Apple>(); 
		//box에 담긴 참조값을 이용해서 pack() 메소드를 호출해보세요.
		box.pack(new Apple());
		//box에 담긴 참조값을 이용해서 unpack() 메소드를 호출하고 리턴되는 값을 
        //fruit라는 지역변수에 담아보세요.
		Apple fruit = box.unPack();
		
		//여기서 생성한 박스에 Melon을 담을 수 있는지 확인해 보세요
		FruitBox<Melon> box2 =new FruitBox<Melon>();
		box2.pack(new Melon());
		Melon fruit2 =box2.unPack();
		
		//Orange도 테스트 해보세요
        //객체 생성시에 Generic 클래스는 생략 가능하다
		FruitBox<Orange> box3 =new FruitBox<>(); 
		box3.pack(new Orange());
		Orange fruit3 =box3.unPack();
		
	}
}

Util Class (유틸리티 클래스)

  • 인스턴스 메서드와 인스터스 변수를 일절 제공하지 않고, 정적 메서드변수만을 제공하는 클래스를 뜻한다.
  • 클래스 본래의 목적인 '데이터와 데이터 처리를 위한 로직의 캡슐화'를 실행하는 것이 아닌,
    '비슷한 기능의 메서드와 상수를 모아서 캡슐화'한 것이 유틸리티 클래스이다.

사용 예시

package test.mypac;

public class Car {
	//필드
	private String name;
	
	//생성자
	public Car(String name) {
		this.name=name;
	}
	//메소드
	public void drive() {
		System.out.println(this.name+" 이(가) 달려요!");
	}
}
---------------------------------------------------------------------------
package test.main;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import test.mypac.Car;

public class MainClass04 {
	public static void main(String[] args) {
		//Car type을 저장할 수 있는 ArrayList 객체를 생성해서
		//참조값을 List 인터페이스 type 지역변수 cars에 담아보세요.
		List<Car> cars = new ArrayList<>();
		
		//Car 객체(3개)를 생성해서 List 객체에 저장해보세요.
		cars.add(new Car("소나타"));
		cars.add(new Car("그랜저"));
		cars.add(new Car("아반떼"));
	
		//일반 for 문을 이용해서 List 객체에 저장된 모든 Car 객체의 
		//drive() 메소드를 순서대로 호출해 보세요.
		for (int i = 0; i < cars.size(); i++) {
			cars.get(i).drive();
		}
		
		System.out.println("------------------");
		
		//확장 for 문을 이용해서 List 객체에 저장된 모든 Car 객체의 
		//drive() 메소드를 순서대로 호출해 보세요.
		for (Car tmp : cars) {
			tmp.drive();
		}
		
		System.out.println("------------------");
		
		//Consumer 인터페이스를 활용해서 List 객체에 저장된 모든 Car 객체의 
		//drive() 메소드를 순서대로 호출해 보세요.
		Consumer<Car> car =new Consumer<Car>() {
			@Override
			public void accept(Car t) {
				t.drive();
			}
		};
		cars.forEach(car);
		
		System.out.println("------------------");
		
		cars.forEach((t)->{
			t.drive();
		});
	}
}

0개의 댓글