Books
제네릭 사용 연습 : 02. 다양한 제네릭 표현
bright jazz music
2022. 11. 2. 22:22
아래의 페이지를 참고하였다.
http://www.tcpschool.com/java/java_generic_various
타입 변수의 제한
- 제네릭은 'T'와 같은 타입변수를 사용하여 타입을 제한한다.
- 이 때 extends 키워드를 사용하면 타입변수에 특정 타입만을 사용하도록 제한할 수 있다.
예시
class AnimalList<T extends LandAnimal> { ... }
위와 같이 클래스의 타입변수를 제한하면 클래스 내부에서 사용되는 모든 타입변수에 제한이 걸린다.
* 이렇게 타입변수를 제한하는 경우, 인터페이스를 구현할 때도 implements가 아닌 extends 키워드를 사용해야 한다.
//인터페이스
interface WarmBlood { ... }
class AnimalList<T extends WarmBlood> {
//implements를 사용해서는 안 된다.
...
}
클래스와 인터페이스를 동시에 상속하고 구현하고 싶다면 &(엠퍼센트) 기호를 사용하면 된다.
class AnimalList<T extends LandAnimal & WarmBlood> { ... }
예제
package com.example.designpatternstudy.test;
import java.util.ArrayList;
import java.util.Iterator;
class LandAnimal{
public void crying() {System.out.println("## Land Animal");}
}
class Cat extends LandAnimal {
@Override
public void crying() {System.out.println("## cat cat");}
}
class Dog extends LandAnimal{
@Override
public void crying() {System.out.println("## dog dog");}
}
class Sparrow{ // LandAnimal 상속 안함
public void crying() {System.out.println("## chup chup");}
}
//LandAnimal과 LandAnimal을 extend한 클래스만 사용 가능
class AnimalList<T extends LandAnimal>{ //T가 아니더라도 상관 없다.
ArrayList<T> animalList = new ArrayList<T>();
void add(T animal){ animalList.add(animal); } //T를 파라미터로 명시
T get(int index){ return animalList.get(index); }
boolean remove(T animal) { return animalList.remove(animal);}
int size(){ return animalList.size(); }
}
public class TestGeneric02 {
public static void main(String[] args){
AnimalList<LandAnimal> landAnimalList = new AnimalList<LandAnimal>();
//Cat, Dog은 파라미터로 사용 가능하지만 Sparrow는 LandAnimal을 상송하지 않았기 떄문에 오류 발생
landAnimalList.add(new LandAnimal());
landAnimalList.add(new Cat());
landAnimalList.add(new Dog());
//landAnimalList.add(new Sparrow()); 오류 발생
System.out.println("<for-loop>");
for (int i = 0; i<landAnimalList.size(); i++){
landAnimalList.get(i).crying();
}
System.out.println("\n<enhanced for-loop>");
for (LandAnimal landAnimal : landAnimalList.animalList) {
landAnimal.crying();
}
System.out.println("\n<Iterator>");
Iterator<LandAnimal> iterator = landAnimalList.animalList.iterator();
while (iterator.hasNext()){
LandAnimal landAnimal = iterator.next();
landAnimal.crying();
}
}
}
/*
<for-loop>
## Land Animal
## cat cat
## dog dog
<enhanced for-loop>
## Land Animal
## cat cat
## dog dog
<Iterator>
## Land Animal
## cat cat
## dog dog
*/
이 코드는 AnimalList 클래스 선언부에 명시한 "extends LandAnimal"을 생략해도 정상 동작한다. 그러나 코드의 명확성을 위해서는 위와 같이 타입의 제한을 명시하는 편이 좋다.