만족은 하되 안주하지는 말자

기록해야 기억한다

프로그래밍/JAVA

다형성: 우리는 왜 List list = new ArrayList(); 라고 쓸까?

D36choi 2022. 4. 4. 23:23
728x90

제목의 질문은 아래로도 대치 가능합니다.

 

왜 우리는 인스턴스 타입을 클래스 대신 인터페이스로 초기화할까?

 

우리는 아래처럼 인스턴스를 생성 및 초기화해서는 안됩니다.

ArrayList<Object> list = new ArrayList<Object>();

  

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

우리는 위처럼 List 인터페이스를 사용해야 합니다.

 

인터페이스를 구체클래스의 위에 타입으로 덧씌우는 것은 캡슐화와 낮은 결합도(loose coupling)의 핵심입니다.

나중에는 테스트코드를 작성하기도 쉬워지고 나중에 구현에 변경사항이 생겨도 변화에 쉽게 대응할 수 있습니다.

 

만약 나중에, 기획자가 요구사항을 바꿔서 ArrayList 가 아니라 Stack 의 기능으로 바꿔야 한다면 해줘야 하는 건 그냥 

ArrayList 를 Stack 클래스로 바꿔주는 겁니다.

List<Object> list = new Stack<Object>();

int size = Counter.sizeOf(list);

 


 

아래와 같은 클래스에서 위 리스트 list를 사용하는 코드가 있을때, 만약 List가 아닌 Stack으로 파라미터의 타입을 선언했다면

우리는 ArrayList 에서 Stack으로 list를 바꿀때, sizeOf() method를 호출하는 코드를 고쳐야만 합니다.

sizeOf() 메서드는 parameter의 타입에 의존적이기 때문입니다.

List 로 한다면 Stack 이든, ArrayList 든 List 를 구현한 구체클래스이기만 한다면 코드를 안바꿔도 됩니다

class Counter {
    static int sizeOf(List<?> items) {
        return items.size();
    }
}

List<Object> list = new Stack<Object>();

int size = Counter.sizeOf(list);

이것을 우리는 결합도를 낮추고 의존성을 분리한다고 합니다. 한코드의 변화가 다른 코드의 변화를 만들어내지 않을수록 생산성이 높아지기 마련입니다.

 

정리하자면, 우리는 자바의 다형성을 활용해 의존도를 낮추고 코드의 재사용성을 높일 수 있습니다.

이런 작성방법을 쓰는 이유는,

위처럼 interface 를 concrete class 보다 선호하는 것이 자바가 지원하는 다형성을 이용해 코드의 결합성을 낮출 수 있기 때문입니다.

 

 

https://stackoverflow.com/questions/9852831/polymorphism-why-use-list-list-new-arraylist-instead-of-arraylist-list-n

 

Polymorphism: Why use "List list = new ArrayList" instead of "ArrayList list = new ArrayList"?

Possible Duplicate: Why should the interface for a Java class be prefered? When should I use List<Object> list = new ArrayList<Object>(); ArrayList inherits from List, so if some

stackoverflow.com