관리 메뉴

bright jazz music

제네릭 사용 연습 : 02. 다양한 제네릭 표현 본문

JAVA

제네릭 사용 연습 : 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"을 생략해도 정상 동작한다. 그러나 코드의 명확성을 위해서는 위와 같이 타입의 제한을 명시하는 편이 좋다.

 

 

 

Comments