List<Dog>은 List<Animal>의 서브클래스인가요? 왜 자바 제네릭은 암시적으로 다형성이 보장되지 않죠?


자바 제네릭이 어떻게 상속과 다형성을 다루는지 혼란스럽네요. 아래와 같은 계층구조가 있다고 가정해보겠습니다. Animal(부모) Dog - Cat(자식)

위 상황에 doSomething(List<Animal> animals) 메소드가 있다고 가정한다면, 상속과 다형성의 법칙에 의거하여, List<Dog>List<Animal>이 같고 List<Cat>List<Animal>이 같다고 할 수 있고 List<Dog>, List<Cat>각각은 doSomething 메소드를 상속받을 것입니다. 그런데 그렇지 않더군요. 위 가정들을 만족시키려면 메소드에 명시적으로 표시를 해야되더군요. Animal의 어떠한 자식 list를 메소드에서 인자로 받아들이기 위해서 다음과 같이 선언해야만 했어요. doSomething(List<? extends Animal> animals).

이런 부분들이 자바의 원칙이라고 생각되는데요. 제가 궁금하건 왜 그런 것인가 입니다. 자바에서의 다형성은 보통 암시적인데 왜 제네릭에 관해서만 다른거죠?

  • 2016년 07월 01일에 작성됨

조회수 116


1 답변


좋아요
0
싫어요
채택취소하기

아뇨 List<Dog>List<Animal>은 같지 않습니다. List<Animal>로 무엇을 할 수 있는지 생각해보세요. List<Animal>에는 어떠한 동물 변수도 추가할 수 있습니다. 물론 cat도 포함해서 말이죠. 논리적으로 새끼강아지 무리에 고양이를 추가할 수 있나요? 절대로 안되죠.

// 좋지 않은 코드입니다. 
List<Dog> dogs = new List<Dog>();
List<Animal> animals = dogs; //잘못된 코드입니다.
animals.add(new Cat());
Dog dog = dogs.get(0); // 과연 안전한 코드일까요?

갑작스레 혼잡한 cat이 반환되겠죠. List<? extends Animal>이 List<Cat>인지 알 수 없기 때문에 List<? extends Animal>에 cat을 추가할 수 없습니다. 리스트에서 값을 찾을 수 있으며 그것이 Animal 이라는 것을 알 수 있을 거예요. 그러나 임의의 animal을 추가할 수는 없죠. 반대의 상황이라면(List<? Super Animal) 리스트에 Animal을 안전하게 추가할 수 있습니다. 그러나 리스트에서 어떤 것이 나올지는 전혀 알 수 없어요. 왜냐면 그 리스트가 List<Object>일 수도 있기 때문이죠..

  • 2016년 07월 02일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close