2023. 12. 3. 14:42ㆍBook/이펙티브 자바
Item21 - 인터페이스는 구현하는 쪽을 생각해 설계하라.
기존 인터페이스에 디폴트 메서드 구현을 추가하는 것은 위험한 일이다.
디폴트 메소드를 선언하면, 그 인터페이스를 구현한 후 디폴트 메소드를 재정의하지 않은 모든 크래스에서 디폴트 구현이 쓰이게 된다. 그렇지만 추가된 메소드가 기존 구현체들과 매끄럽게 연동되리란 보장이 없다. 자바8 이전의 클래스들은 인터페이스가 한번 정의되면 그 이후에 추가되는 메서드가 없다는 가정하에 만들어졌기 때문이다.
인터페이스를 설계할 때는 세심한 주의를 기울여야 한다.
디폴트 메서드는 기존 구현체에 런타임 오류를 일으킬 수도 있으니 기존 인터페이스에 디폴트 메소드는 꼭 필요한 경우인 경우에만 추가하자
public class SuperClass {
//private!!
private void hello() {
System.out.println("hello");
}
}
==============================================================================
public interface MarketInterface {
default void hello() {
System.out.println("hello");
}
}
==============================================================================
public class SubClass extends SuperClass implements MarketInterface{
public static void main(String[] args) {
SubClass subClass = new SubClass();
subClass.hello();
}
}
=>
Exception in thread "main" java.lang.IllegalAccessError: class effective.study.chapter04.item21.SubClass tried to access private method 'void effective.study.chapter04.item21.SuperClass.hello()' (effective.study.chapter04.item21.SubClass and effective.study.chapter04.item21.SuperClass are in unnamed module of loader 'app')
at effective.study.chapter04.item21.SubClass.main(SubClass.java:7)
subClass에서 호출한 hello() 메서드는 인터페이스의 hello() 디폴트 메서드가 아니라 SuperClass의 hello() 메서드를 호출해 private 한 메서드를 호출했다고 에러가 난다.
새로운 인터페이스를 설계할 때는 테스트를 충분히 해보고 기존 인터페이스에 디폴트 메소드는 꼭 필요한 경우에 추가하자
Item22 - 인터페이스는 타입을 정의하는 용도로만 사용하라
상수를 정의하는 용도로 인터페이스를 사용하지 말 것!
public interface PhysicalConstants {
// 아보가드로 수 (1/몰)
static final double AVOGADROS_NUMBER = 6.022_140_857e23;
// 볼츠만 상수 (J/K)
static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;
// 전자 질량 (kg)
static final double ELECTRON_MASS = 9.109_383_56e-31;
}
===================================================================
public class MyClass implements PhysicalConstants{
public static void main(String[] args) {
System.out.println(BOLTZMANN_CONSTANT);
}
}
- 클래스 내부에서 사용할 상수는 내부 구현에 해당한다.
- 내부 구현을 클래스의 API로 노출하는 행위가 된다.
=> 캡슐화가 깨짐
- 클라이언트에 혼란을 준다.
=> MyClass를 사용할 때 인터페이스가 어떤 의미를 가지는지, 데이터 타입을 인터페이스로 사용해야 하는지 등등
상수를 정의하는 방법
- 특정 클래스나 인터페이스
=> 특정 클래스나 인터페이스에 강하게 연관된 상수일 경우
- 열거형
- 인스턴스화 할 수 없는 유틸리티 클래스
public class PhysicalConstants {
private PhysicalConstants() { } // 인스턴스화 방지
// 아보가드로 수 (1/몰)
public static final double AVOGADROS_NUMBER = 6.022_140_857e23;
// 볼츠만 상수 (J/K)
public static final double BOLTZMANN_CONST = 1.380_648_52e-23;
// 전자 질량 (kg)
public static final double ELECTRON_MASS = 9.109_383_56e-31;
}
'Book > 이펙티브 자바' 카테고리의 다른 글
Item24 - 멤버 클래스는 되도록 static으로 만들라 (1) | 2023.12.03 |
---|---|
Item23 - 태그 달린 클래스보다는 클래스 계층 구조를 활용하라 (0) | 2023.12.03 |
Item20 - 추상 클래스보다 인터페이스를 우선하라. (0) | 2023.12.02 |
Item19 - 상속을 고려해 설계하고 문서화하라. 그렇지 않다면 상속을 금지하라 (1) | 2023.12.02 |
Item18 - 상속보다는 컴포지션을 사용하라 (2) | 2023.11.30 |