[Effective Java] 아이템 64 : 객체는 인터페이스를 사용해 참조하라

Loopy·2022년 11월 18일
0

이펙티브 자바

목록 보기
62/76
post-thumbnail

객체의 실제 클래스를 사용할 상황은, 오직 생성자로 생성할 때 뿐이다.

따라서 적합한 인터페이스만 있다면 매개변수 뿐 아니라 반환값, 변수, 필드 전부 인터페이스 타입으로 선언해야 한다. 인터페이스를 타입으로 사용하는 프로그램은 훨씬 유연해지기 때문이다.

좋은 예

Set<Son> sonSet = new LinkedHashSet<>(); // 인터페이스를 타입으로 사용

나쁜 예

LinkedHashSet<Son> sonSet = new LinkedHashSet<>(); // 클래스를 타입으로 사용

만약 나중에 구현 클래스를 교체하고자 한다면, 새 클래스의 생성자를 호출해주기만 하면 된다. 다른 코드는 전혀 손대지 않고 새로운 클래스로 교체가 가능해지는 것이다!

Set<Son> sonSet = new HashSet<>(); 

주의 사항

하지만 LinkedHashSet과 달리 HashSet은 반복자의 순회 순서를 보장하지 않는 특징을 가지고 있다.

이처럼 원래 클래스가 인터페이스의 일반 규약 의외의 특별한 기능을 제공하며, 주변 코드가 이 기능에 기대어 동작한다면 새로운 클래스도 같은 기능을 제공해야 한다는 것을 주의하자.

☁️ 적합한 인터페이스가 없는 경우

1. 값 클래스

String, BigInteger 와 같은 값 클래스들은 적합한 인터페이스가 없다. (주로 final로 확장을 막아놓은 경우가 많다)

이런 값 클래스는 매개변수, 변수, 필드, 반환 타입으로 사용해도 괜찮다.

2.클래스 기반 작성된 프레임워크

클래스 기반으로 작성된 프레임워크가 제공하는 객체들은, 적합한 인터페이스가 없다.
OutputStreamjava.io 패키지의 여러 클래스가 이 부류에 속한다.

3.인터페이스에 없는 특별한 메서드를 제공하는 클래스

PriorityQueue 클래스는 Queue 인터페이스에 없는 comparator 메서드를 제공한다. 클래스 타입을 직접 사용하는 경우는 이런 추가 메서드를 꼭 사용해야 하는 경우로 최소화해야 한다.

📚 핵심 정리
적합한 인터페이스가 있다면 타입으로 사용하고, 적합한 인터페이스가 없다면 클래스의 계층구조 중 필요한 기능을 만족하는 가장 덜 구체적인(상위의)클래스 타입으로 사용하자.

profile
개인용으로 공부하는 공간입니다. 잘못된 부분은 피드백 부탁드립니다!

0개의 댓글