제목의 질문은 아래로도 대치 가능합니다.
왜 우리는 인스턴스 타입을 클래스 대신 인터페이스로 초기화할까?
우리는 아래처럼 인스턴스를 생성 및 초기화해서는 안됩니다.
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 보다 선호하는 것이 자바가 지원하는 다형성을 이용해 코드의 결합성을 낮출 수 있기 때문입니다.
'프로그래밍 > JAVA' 카테고리의 다른 글
[JAVA] 10진수 n진수 변환 (n진법 변환) (0) | 2022.05.07 |
---|---|
[java] Date, LocalDateTime 사용법 간단 정리 (0) | 2022.04.24 |
List 2차원 배열 만들기 (Array of ArrayList, 2d array with ArrayList) (0) | 2022.02.10 |
[Java] 정수 콤마 넣기 (천원 단위 변환, 금액 변환) (0) | 2021.08.02 |
[Java] 문자열 붙이기에 반드시 StringBuilder 를 안해도 된다 (1) | 2021.06.05 |