-
제네릭 클래스의 이해와 설계JAVA/Generic 2020. 10. 18. 18:17
1. 제네릭 클래스가 필요한 이유
아래와 같이 클래스가 있다고 하자.
위의 클래스에서 구현의 편의만 놓고 보면, FruitBox 클래스가 더 좋아 보인다.
그런데, FruitBox 클래스는 자료형에 안전하지 못하다는 단점이 있다.
AppleBox와 OrangeBox는 구현의 불편함이 따르는 단점이 있다.
그러나 자료형에 안전하다는 장점이 있다.
AppleBox, OrangeBox의 장점인 자료형의 안전성과 FruitBox의 장점인 구현의 편의성을 한데 모은 것이
바로 제네릭이다.
자료형의 안전성에 대한 예제1
프로그램 실행 및 에러 발생 문구
위에서 실행 중간에 Class Casting Exception이 발생하는데
위와 같이 실행 중간에 발생하는 예외는 컴파일 과정에서 발견되는 오류 상황보다 발견 및 정정이 어렵다.
즉, 이는 자료형에 안전한 형태가 아니다.
자료형의 안전성에 대한 예제2
프로그램 실행 및 에러 발생 문구
컴파일 과정에서, 메소드 Store에 문자열 인스턴스가 전달될 수 없음이 발견된다.
이렇듯 컴파일 과정에서 발견된 자료형 관련 문제는 발견 및 정정이 간단하다.
즉, 이는 자료형에 안전한 형태이다.
2. 제네릭 클래스 설계
아래의 클래스를 제네릭 클래스로 만들어보자.
아래의 클래스가 위의 FruitBox클래스의 제네릭 클래스이다.
T에 해당하는 자료형의 이름은 인스턴스를 생성하는 순간에 결정이 된다.
3. 제네릭 클래스 기반 인스턴스 생성 예제
프로그램 실행결과
프로그램을 분석해보자.
인스턴스 생성 시, 결정된 T의 자료형에 일치하지 않으면 컴파일 에러가 발생하므로
자료형에 안전한 구조이다.
4. 제네릭 클래스의 생성자 호출
위의 클래스에 생성자를 추가한 내용이다.
프로그램 실행결과
제네릭 클래스의 생성자 정의방법과 일반 클래스의 생성자 정의방법과는 차이가 없다.
소스 코드
더보기class Orange { int sugarContent; // 당분 함량 public Orange(int sugar) {this.sugarContent = sugar;} public void ShowSugarContent() { System.out.println("당도 : " +sugarContent); } } class Apple { int weight; // 사과의 무게 public Apple(int weight) {this.weight = weight;} public void ShowAppleWeight() { System.out.println("무게 : " +weight); } } class FruitBox<T> { T item; // 생성자 public FruitBox(T item){ this.item = item; } public void Store(T item) {this.item = item;} public T PullOut() { return this.item;} } public class Exam3 { public static void main(String[] args) { FruitBox<Orange> orBox = new FruitBox<Orange>(new Orange(10)); Orange org = orBox.PullOut(); org.ShowSugarContent(); FruitBox<Apple> apBox = new FruitBox<Apple>(new Apple(20)); Apple app = apBox.PullOut(); app.ShowAppleWeight(); } }
5. 제네릭 클래스의 규칙
기본 자료형의 이름은 제네릭에 사용 불가하다.
그 이유는 제네릭은 클래스와 인스턴스에 관한 이야기이다.
'JAVA > Generic' 카테고리의 다른 글
제네릭 변수의 참조와 상속의 관계 (0) 2020.10.18 제네릭 메소드와 배열 (0) 2020.10.18 매개변수의 자료형 제한 (0) 2020.10.18 제네릭 메소드 (0) 2020.10.18