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

조회수 1242회

자바 제네릭이 어떻게 상속과 다형성을 다루는지 혼란스럽네요. 아래와 같은 계층구조가 있다고 가정해보겠습니다. 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).

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

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>일 수도 있기 때문이죠..

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)