2013-06-26 1 views
1

아래처럼 TypeA 또는 TypeB가 될 수있는 Map을 허용해야합니다.여러 클래스가있는 상한 - Java generics

Map<Animal, List<TypeA/TypeB>> 

어떻게 선언합니까? 상한에 대해 두 클래스를 지정할 수 없습니다.

Map<Animal, List<? extends Object>> OR Map<Animal, List<Object>> 

이 너무 큽니다. TypeA 또는 TypeB로 제한하려고했습니다

더 좋은 방법이 있습니까?

TypeA 및 TypeB를 인터페이스로 감쌀 수 없습니다.

편집 : 답변에서 사용자 정의 유형으로는 가능하지 않습니다. 후속 질문은 단지 <? extends Object>을 사용하는 경우 어떻게 유형을 확인해야합니까? TypeA 또는 TypeB입니다. instanceof를 사용해야합니까? 코드 샘플?

+1

'TypeA'과'TypeB'이 공분산되지 않는 타입이라면,'? 객체를 확장한다. 너가 그런 넓은 유형을 원하지 않으면, 너는 2 가지의 유형 사이 어떤 관계를 창조해야한다. –

답변

3

명백한 해결책은 필요한 동작을 포함하는 TypeATypeB의 상위 유형을 소개하는 것입니다.

다른 접근법은 어댑터를 사용하는 것입니다. 너희가 옛날부터 인용하자 Gang of Four 서적 :

클라이언트가 기대하는 다른 인터페이스로 클래스의 인터페이스를 변환한다. 어댑터는 호환되지 않는 인터페이스 때문에 달리 작동 할 수없는 클래스 작업을 허용합니다.

여기에서는 어댑터 유형을 소개합니다 (이보다 더 좋은 이름 만 사용 가능).

interface Ab { 
    void someOp(); 
} 

그러면 기존 개체를 래핑 할 수 있습니다.

public static Ab asAb(final TypeA obj) { 
    return new Ab() { 
     public void someOp() { 
      obj.someOp(); 
     } 
    }; 
} 

맵은 어댑터 유형을 값으로 사용할 수 있습니다.

Map<Animal, List<Ab>> 

기존 코드에서이 문제가 발생했을 때지도에 실제로 두 개의 분리 된지도가 포함되어 있었기 때문입니다. 쉬운 해결책은 두 개의 맵을 사용하는 것입니다.

+0

그는 공용 인터페이스를 추출 할 수 없다고 명시 적으로 말했기 때문에 어댑터에 대해 +1 – darijan

+0

TypeA 또는 TypeB를 만질 수 없습니다. 어댑터가 여전히 관련성이 있습니까? –

+0

@KevinRave 그래. 조금 더 설명을 추가했습니다. –