본문 바로가기

JAVA/Effective Java

item 64) 객체는 인터페이스를 사용해 참조하라.

728x90
  • 적합한 인터페이스만 있다면 매개변수 뿐만 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라.
  • 인터페이스 타입을 사용할 경우 프로그램이 더 유연해짐(구현 클래스만 교체하면됨
  • 원래의 클래스가 인터페이스의 일반 규약 이외의 특별한 기능을 제공하며 주변 코드가 이 기능에 기대어 동작하다면 새로운 클래스도 반드시 같은 기능을 제공해야한다.
  • 선언 타입과 구현타입을 동시에 바꿀수 있으니 괜찮을 수 있을거라고생각가능 X 클라이언트에서 기존 타입의 메소드를 사용할 경우 컴파일  에러 발생 가능

 

//좋은 예
Set <String> sonSet = new LinkedHashSet<>();
Set <String> sonSet = new HashSet<>(); //구현체 변경


//나쁜 예
LinkedHashSet<String> sonSet = new LinkedHashSet<>();

 

구현타입을 바꾸는 이유?

  • 원래 것보다 성능이 좋거나 신기능을 제공함(HashMap -> EnumMap 속도 향상, 순회 순서도 키의 순서와 같아짐 단, 키가 열거타입만 가능) => 키의 타입과 상관없이 사용할수 있는 LinkedHashMap일 경우 성능은 비슷하게 유지하면서 순서 조절 가능해짐

 

 

구현 클래스로  피치못하게 해야할 경우

 

1. 적합한 인터페이스가 없다.(BigInteger, String)

2. 클래스 기반으로 작성된 프레임워크가 제공하는 객체(OutPutStream) => 인터페이스가 아니더라도 기반 클래스인 추상 클래스를 사용하여 참조 !

3. 인터페이스에는 없는 구현 클래스의 특별한 메서드를 사용하려고 할 경우 (PriorityQueue의 compare 메서드, LinkedHashMap의 removeEldestEntry )