Skip to content

Latest commit

 

History

History
65 lines (53 loc) · 3.07 KB

인터페이스는_타입을_정의하는_용도로만_사용하라_배키.md

File metadata and controls

65 lines (53 loc) · 3.07 KB

[item 22] 인터페이스는 타입을 정의하는 용도로만 사용하라

인터페이스의 사용 용도

인터페이스는 아래 용도로만 사용해야 한다!

타입을 정의하는 것. 즉, 즉 인터페이스를 구현한 클래스는 자신의 인스턴스로 무엇을 할 수 있는지 인터페이스를 통해 클라이언트에게 알릴 수 있다.

인터페이스 사용 용도와 맞지 않는 예

상수 인터페이스

상수 인터페이스란 메서드 없이 static final 필드로만 가득 찬 인터페이스이다.

public interface PhysicalConstants {
	// 아보가드로 수
	static final double AVOGADROS_NUMBER = 6.022_140_857e23;

	// 볼츠만 상수
	static final double BOLTZMANN_CONSTANT = 1.380_648_52e23;

	// 전자 질량
	static final double ELECTRON_MASS = 9.109_383_56e-31;
}

상수 인터페이스는 아래와 같은 문제점이 있다.

  • 클래스 내부에서 사용하는 상수는 인터페이스가 아니라 내부 구현에 해당한다.
    • 상수 인터페이스를 구현한 하위의 모든 클래스가 상수 인터페이스의 모든 값에 접근할 수 있다. 이는 내부 구현을 외부에 노출하는 것이다.
  • final이 아닌 클래스가 상수 인터페이스를 구현한다면 모든 하위 클래스의 이름 공간이 그 인터페이스가 정의한 상수들로 오염되어 버린다.
    • 아래 코드를 보자.
      public interface Constants {
          int VALUE = 10;
      }
      
      public class MyBaseClass implements Constants {
          // 클래스 내부 구현
      }
      
      public class MySubClass extends MyBaseClass {
          // 클래스 내부 구현 
      }
    • MyBaseClass가 final이 아니라면 MySubClass가 VALUE를 사용할 수 있게 된다. MySubClass는 VALUE를 사용하지 않아도 되는 상황인데, 이름 공간에 VALUE라는 상수 값이 존재하게 된다.

만약 상수를 공개할 목적이라면 선택할 수 있는 방법들

  • 특정 클래스나 인터페이스와 강하게 연관된 상수라면 그 클래스나 인터페이스 자체에 추가하자. (위 코드 처럼 상수 인터페이스에 모아두지 말자!)
    • ex. Integer 클래스의 MIN_VALUE, MAX_VALUE;
  • 열거 타입으로 나타내기 적합한 상수라면 열거 타입으로 만들자.
  • 인스턴스화 할 수 없는 유틸리티 클래스에 담아 공개하자.(상수 유틸리티 클래스)
    • 아래 코드는 상수 인터페이스를 상수 유틸리티 클래스로 만든 예이다.
      public class PhysicalConstants {
      
          private PhysicalConstants() {} // 객체를 생성시키 않도록 함
          
          // 아보가드로 수
          static final double AVOGADROS_NUMBER = 6.022_140_857e23;
      
          // 볼츠만 상수
          static final double BOLTZMANN_CONSTANT = 1.380_648_52e23;
      
          // 전자 질량
          static final double ELECTRON_MASS = 9.109_383_56e-31;
      }

핵심 정리

인터페이스는 타입을 정의하는 용도로만 사용하자. 상수 공개용 수단으로 사용하지 말자!