김준
20
2019-02-01 18:12:24 작성 2019-02-01 18:12:46 수정됨
6
588

ArrayList를 사용할 때 레퍼런스 변수를 List 타입으로 만드는 이유가 궁금합니다.


안녕하세요. 1년차 새내기 개발자입니다.

회사에서 자바를 사용하는데, 제가 써 본 적이 없어서 처음부터 공부하는 중입니다.

List<String> list = new ArrayList<String>();

공부하면서 예제를 보니 위와 같은 방식으로 선언된 것이 참 많더군요.

ArrayList 인스턴스를 만들었는데 ... 왜 그것을 담는 레퍼런스 변수를 List 인터페이스로 선언을 하는걸까요?

사실 구글링을 통해 저런 식으로 사용하는 이유를 대략적으로 이해하긴 했습니다.(http://egloos.zum.com/xxwony/v/33456)

그러나 여전히 풀리지 않는 의문은

기껏 ArrayList로 생성해서 List 레퍼런스 변수로 참조시키면, 다형성의 특성으로 인해 ArrayList가 아닌 List로써 사용되는 것이 아닌가요?

따라서 ArrayList만의 멤버는 사용하지 못하게 될 것이구요. 그렇다면

List<Integer> list1 = new ArrayList<>(Arrays.asList(4, 3, 25, 3, 4));
List<Integer> list2 = new LinkedList<>(Arrays.asList(4, 3, 25, 3, 4));

위 코드에서 list1과 list2는 사실상 같게 되는건가요? 그럼 애초에 List 인터페이스를 상속받기만 하면 어떤 것으로 선언하던지 상관이 없게 되는 건지 ...

처음 접하는 개념이라 너무 헷갈리고 어려운게 많은 것 같습니다 ㅠㅠ

고수님들의 답변을 기다리겠습니다.

0
0
  • 답변 6

  • 제르맹
    312
    2019-02-01 18:26:04

    인터페이스는 틀입니다.

    구현체는 그 틀에 맞추어 만들어져야하고요.

    예를들어 우리는 인간이라는 틀에 맞추어 태어났지만 제각각 생김세는 다릅니다.


    ArrayList와 LinkedList 역시 List라는 틀에 맞춰졋만들어져서 동일한 이름의 메소드를 갖지만 그 안의 로직은 전혀 다름니다.

    우리 모두 얼굴이 있지만 제각각의  모습을 하고 있듯이요

    1
  • 김준
    20
    2019-02-01 18:39:22

    아하 ... 구현체에서 어떻게 만들었나에 따라 같은 메소드를 호출해도 다른 방식으로 실행이 되는군요.

    구체적인 설명 감사합니다!! ㅎㅎ 

    0
  • 나도아빠다
    2k
    2019-02-01 18:47:06

    심플하게 설명하려니 어려워서 길게 설명합니다...

    1. 형태변형이 자유롭습니다.

    ArrayList는 LinkedList로 못바꿉니다만 list는 바꿀수있습니다.인터페이스와 다형성.

    물론 이용도로는 쓸일은 잘없습니다.

    바꾸는 용도가 아니라 두가지의 리스트를 함께 사용할 경우가 만약 존재한다고 했을때도 다형성이 중요하게 작용합니다. 

    벡터와 어레이리스트 두가지의 목록을 함께 합친다거나, 그 두개를 비교해야한다거나.. 이런경우 말이죠.

    둘다 list형으로 받으면 바로 체크가 가능합니다.


    2. ArrayList의 주요 메서드들은 List의 메소드를 구현한겁니다.

    SubList같은경우 List를 리턴하지요. arrayList가아니라.

    arrayList로 쓴다고 하면 Arraylist.sublist로 가져온 목록을 다시 ArrayList로 바꿔서 작업해야 소스가 통일성이 있을겁니다. 

    어느쪽이 개발이 더 편할지는 설명을 생략하겠습니다.


    3. List인터페이스에는 없지만 ArrayList에만 존재하는 메소드가 존재하고, 그걸 반드시써야한다면 ArrayList 그대로 사용하는게 맞습니다만, 그런 메소드가 얼마나 되는지 자바독 한번 살펴보세요. 

    참고로 있긴있습니다. 그나마도 ArrayList가 따로구현한건 아니지만.


    4. 목록을 받아 처리하는 메소드를 만들때

    public void setList(ArrayList l)

    public void setList(List l)

    둘중에 어느걸로 만드는게 프로그램적으로 더 나을까요?

    5. 정작 간단한 프로그램 만들다보면 arraylist list= new arraylist()로 만들어도 크게 문제될게 없긴합니다.

    다형성이니 은닉화니 캡슐화니.. 단어는 어려운데 안지켜도 적당히 만들수는 있어요. 코딩하는 당장은 솔직히 크게 안와닿습니다.

    다만 나중에 프로그램을 유지보수하고, 확장하고, 프로그램끼리 연관이 생기고 하다보면, 처음부터 구현체로 만들어버리는것과 인터페이스를 이용하는것이 얼마나 큰차이가 있는지 뒤늦게 알게되는 경우가 많아요.


    결론은 인터페이스는 사랑입니다.



    1
  • fender
    14k
    2019-02-01 19:00:21 작성 2019-02-01 19:02:45 수정됨

    이전에 비슷한 질문에 답을 달 때 들었던 비유인데, 만약에 못을 박는 것이 목적이라면 조수에게 "공구함에 가서 망치를 가져와라"라고 말하면 그만이지 굳이 "공구함에서 길이가 약 30cm 가량이고 무게 1kg 정도 되는 목재의 손잡이로 된 망치를 들고와라"라고 할 필요가 없다는 것이 핵심입니다.

    목공이 조수에게 부탁을 할 때나, 개발자가 코드를 짤 때나 의도를 명확하고 간결하게 표현하는 것은 중요합니다. 목적이 못을 박는 것이고, 순서가 보존되는 컬렉션에 값을 보관하는 것이라면 그냥 '망치' 또는 'List'라고 하면 그만입니다.

    그 밖에 망치의 손잡이가 목재로 되어있다거나 List의 인터페이스가 배열을 기반으로 구현되었다거나 하는 것은 모두 '구현상 디테일'에 해당하는 부분입니다. 그런 부분을 불필요하게 강제하면 의도를 오해할 수도 있고, 또 실제 길이가 좀 짧은 망치나 `LinkedList` 같은 인스턴스가 이미 있음에도 조건을 충족하지 못해서 바로 원하는 작업을 실행할 수 없는 경우도 있을 수 있습니다.

    따라서 특히 인터페이스나 공용 클래스 등의 시그네처에 표현되는 유형은 가능하면 의도를 명확하게 할 수 있는 선에서 최대한 일반적인 상위 유형을 명시하는 것이 좋은 습관이라고 할 수 있습니다.

    3
  • 사는게힘듭니다
    2019-02-01 21:36:03

    ArrayList객체를 생성해 그 객체의 메모리위치주소값을 list 변수에 담았는데 그변수의 자료형이 ArrayList가 아니라 List를 써도 되는 이유는

    자바에서 Collection 이 관리하는 인터페이스중 List인터페이스가 있는데 그 인터페이스를 구현받은 클라스가 ArrayList이기때문에  자료형을 ArrayList 또는 List를 써도 되는거에요.

    1
  • 김준
    20
    2019-02-07 13:59:46
    고수님들의 친절한 설명 너무나도 감사합니다!! ㅠㅠ 덕분에 감을 잡아가고 있습니다. 이미 채택을 해버려서 .. 드릴 것이 추천밖에 없지만 다시 한번 감사드립니다 :)
    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.