1. 제네릭 사용 예제
class DogHospital {
private Dog dog;
public void set(Dog dog) { this.dog = dog; }
public Dog bigger(Dog target) {
return dog.getSize() > target.getSize() ? dog : target;
}
}
class CatHospital {
private Cat cat;
public void set(Cat cat) { this.cat = cat; }
public Cat bigger(Cat target) {
return cat.getSize() > target.getSize() ? cat : target;
}
}
문제점
- 코드 중복 심함 (DogHospital, CatHospital 따로 필요)
- 타입이 다르면 컴파일 오류로 막힘은 좋지만... 중복이 너무 많음
(1) 다형성 활용
class AnimalHospitalV1 {
private Animal animal;
public void set(Animal animal) { this.animal = animal; }
public Animal getBigger(Animal target) {
return animal.getSize() > target.getSize() ? animal : target;
}
}
장점
- 코드 재사용성 UP (동물이면 뭐든 처리 가능)
단점
- DogHospital.set(cat)처럼 타입을 잘못 넣어도 컴파일 통과 → 런타임 오류 발생 가능
- 반환 시 다운 캐스팅 필요 → 타입 안정성 ↓
(2) 제네릭
class AnimalHospitalV2<T> {
private T animal;
public T getBigger(T target) {
// animal.getSize() ❌ 컴파일 오류
return null;
}
}
문제점
- T는 아무 타입이나 들어올 수 있음 (Integer 등도 가능)
- 자바는 T를 Object로 간주 → getSize(), sound() 불가
- 결국 Animal의 기능 사용 못함
(3) 타입 매개변수 제한(<T extends Animal>)
package com.example.generic.ex3;
import com.example.generic.animal.Animal;
public class AnimalHospitalV3<T extends Animal> {
private T animal;
public void set(T animal) {
this.animal = animal;
}
public void checkup() {
// 상속을 통한 매개변수 제한
// Animal의 메서드 사용가능
System.out.println("동물 이름: " + animal.getName());
System.out.println("동물 크기: " + animal.getSize());
animal.sound();
}
public T bigger(T target) {
return animal.getSize() > target.getSize() ? animal : target;
}
}
package com.example.generic.ex3;
import com.example.generic.animal.Animal;
import com.example.generic.animal.Cat;
import com.example.generic.animal.Dog;
public class AnimalHospitalMainV3 {
public static void main(String[] args) {
AnimalHospitalV3<Dog> dogHospital = new AnimalHospitalV3<>();
AnimalHospitalV3<Cat> catHospital = new AnimalHospitalV3<>();
Dog dog = new Dog("멍멍이1", 100);
Cat cat = new Cat("냐옹이1", 300);
// 개 병원
dogHospital.set(dog);
dogHospital.checkup();
// 고양이 병원
catHospital.set(cat);
catHospital.checkup();
// 문제 1: 개병원에 고양이 전달
// dogHospital.set(cat); // 다른 타입 입력: 컴파일 오류
// 문제 2: 개 타입 반환 -> 제네릭으로 인해 캐스팅 불필요
dogHospital.set(dog);
Dog biggerDog = dogHospital.bigger(new Dog("멍멍이2", 200));
System.out.println("biggerDog = " + biggerDog);
}
}
장점
- T는 반드시 Animal의 자식만 가능
- getSize(), sound() 등 Animal 기능 사용 가능
- AnimalHospitalV3<다른 타입> 사용 시 컴파일 오류! ❌
정리
| 항목 | 내용 |
| T | 타입 매개변수. 어떤 타입이든 들어올 수 있음 |
| <T extends Animal> | 타입 제한. Animal 또는 그 자식만 허용 |
| 코드 재사용성 | 제네릭 도입으로 클래스 수 최소화 |
| 타입 안전성 | 다형성 대신 제네릭으로 컴파일 단계에서 오류 포착 가능 |
'Java' 카테고리의 다른 글
| 자바 중급 2편 - 제네릭(4) (0) | 2025.06.01 |
|---|---|
| 자바 중급 2편 - 제네릭(3) (0) | 2025.05.31 |
| 자바 중급 2편 - 제네릭(1) (0) | 2025.05.11 |
| Java 중급 1 - 예외처리(4) (0) | 2025.05.10 |
| Java 중급 1 - 예외처리(3) (0) | 2025.05.05 |