프로그래밍안드로이드 개발자

코틀린에서 확장 속성(Extension Properties)이란 무엇이며, 어떻게 구현되며, 일반 속성과 비교할 때 어떤 제한이 있나요?

Hintsage AI 어시스턴트로 면접 통과

답변.

확장 속성은 클래스에 대한 확장으로, 상태(재저장 필드)를 추가할 수 없고 getter와 setter를 추가할 수 있습니다. 자바에서는 이러한 기능을 지원하지 않으며, 유틸리티 메소드를 작성하는 것이 유사한 기능입니다. 기능을 추가하기 위해 정적 메소드나 래퍼 객체를 사용하는 것이 역사적으로 필요했습니다.

문제: 외부 클래스에 종종 필요한 속성이 부족한 경우가 많습니다. 캡슐화를 파괴하지 않고 클래스의 기능을 간결하고 안전하게 확장하고 싶습니다.

해결책: 코틀린에서는 일반 속성처럼 보이는 확장 속성을 선언할 수 있지만 함수의 형태로 구현됩니다. 이를 통해 소스 코드에 접근할 수 없는 타입들을 편리하게 확장할 수 있습니다.

코드 예시:

val String.firstChar: Char get() = this[0] println("Kotlin".firstChar) // K

주요 특징:

  • 확장 속성은 구문적 설탕으로, 상태를 가질 수 없습니다(재저장 필드를 선언할 수 없음).
  • set 속성의 경우 함수로만 구현됩니다.
  • 클래스의 public API와만 작동하며, private 멤버에 접근할 수 없습니다.

함정 질문.

확장 속성에 재저장 필드(상태)를 추가할 수 있나요?

아니요, 확장 속성은 값을 즉석에서 계산할 뿐이며 상태를 저장할 수 없습니다.

확장 속성이 상속된 클래스에서 속성을 재정의할 수 있나요?

아니요, 확장 속성(및 확장 함수)은 본질적으로 정적입니다: 재정의되거나 가상일 수 없습니다.

확장 속성이 어떻게 컴파일되며, 왜 일반 속성과 유사한 구문이 아닐까요?

확장 속성은 실제로 정적 getter(및/또는 setter) 함수로 컴파일됩니다. 이들은 클래스의 엔티티에 포함되지 않으며, 선언된 파일의 컨텍스트에서만 보입니다.

전형적인 오류 및 안티 패턴

  • 확장 속성 내부에서 클래스의 private 멤버에 접근할 것으로 예상함
  • 확장 속성을 통해 상태 저장을 구현하려고 하는 시도
  • 필요하지 않은 경우 일반 속성 대신 확장 속성을 남용함

실제 사례

부정적 사례

개발자가 표준 Android View에 대한 상태 "방문 여부"를 저장하기 위해 확장 속성을 추가하려고 했습니다:

var View.isVisited: Boolean get() = ... set(value) { ... } // 오류: 저장 불가

장점:

  • 구문이 간결함

단점:

  • 불가능한 기능(상태 저장 불가)에 대한 기대
  • 실행 중 오류

긍정적 사례

String에 대한 확장 속성을 구현하여 확장된 형식을 얻었습니다:

val String.asTitle: String get() = this.replaceFirstChar { it.uppercase() }

장점:

  • 기능 추가의 편리함
  • 외부 유틸리티가 필요 없음
  • 쉬운 유지 관리

단점:

  • 상태 저장이 없음(필요하다면 다른 패턴이 필요함)