2026-01-13

1일 1아티클

LY

불변 클래스의 상속

문제 상황

  1. 상속이 불변성을 깨뜨린다 ```java // 부모 클래스: 불변 리스트 // 상속이 가능하도록 열려 있음 (Java에서는 기본적으로 상속 가능) public class ImmutableIntList { // 자식 클래스에서 접근할 수 있도록 protected로 선언 protected final int[] valueArray;

    public ImmutableIntList(int… values) { this.valueArray = values; }

    public int get(int index) { return valueArray[index]; } }

// 자식 클래스: 부모는 ‘불변’이라지만, 자식은 ‘가변’으로 만들어버림 public class MutableIntList extends ImmutableIntList { public MutableIntList(int… values) { super(values); }

  // 부모의 배열에 접근해서 값을 바꿔버리는 메서드 추가
  public void set(int index, int value) {
      this.valueArray[index] = value;
  }   }

MutableIntList mutable = new MutableIntList(1, 2, 3); ImmutableIntList immutable = mutable; // 다형성: 부모 타입으로 참조

// ‘불변’ 리스트라고 믿고 있는데, 값이 바뀜! 😱 mutable.set(0, 999); System.out.println(immutable.get(0)); // 999 출력

2. 메서드 오버라이딩
```java
  public class SneakyIntList extends ImmutableIntList {
      private int cheatValue = 0;

      // get 메서드를 조작해서 매번 다른 값을 주게 만듦
      @Override
      public int get(int index) {
          if (cheatValue > 0) return cheatValue;
          return super.get(index);
      }

      public void changeCheatValue(int value) {
          this.cheatValue = value;
      }
  }

해결 방법

  • 확실한 불변성 보장을 하려면, 클래스를 상속하지 못하게 막을 것
    • Java의 경우, 클래스의 final 선언 및 필드의 private final 선언
      // 상속 불가능하게 final 클래스로 선언
      public final class SafeImmutableIntList {
        private final int[] valueArray;
      
        public SafeImmutableIntList(int... values) {
            // 배열의 참조가 아닌 복사본을 저장해야 안전함 (방어적 복사)
            this.valueArray = values.clone();
        }
      
        public int get(int index) {
            return valueArray[index];
        }
      
        // set 메서드 없음
      }
      
  • 가변 객체는 불변 객체 상속 X
  • 불변 객체도 가변 객체 상속 X (부모의 set 메서드가 자식에게 노출되어 런타임 에러 유발)
  • 필요하다면, 읽기 전용의 공통 부모를 두고 각각 상속받을 것!

오늘 배운 것

  1. 아이디어 2차 컨펌 (기능 구체화)

내일 할 일

  1. 아이디어 3차 컨펌 (교보재 신청)

참고자료

results matching ""

    No results matching ""