프로그래밍백엔드 개발자

코틀린에서 중첩(nested) 클래스와 내부(inner) 클래스 선언 및 사용의 특징을 설명하십시오. 언제 적용해야 하며, 자바의 중첩 클래스와의 차이점은 무엇인지, 어떤 함정이 존재하는지 설명하십시오.

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

답변.

코틀린에서 중첩(nested) 클래스와 내부(inner) 클래스는 외부 클래스 내에서 기능을 논리적으로 그룹화하고 캡슐화하는 데 사용됩니다.

질문의 역사

중첩 클래스의 아이디어는 자바에서 코드 구조를 만들고 보조 컴포넌트를 주요 클래스 안에 격리하기 위한 방법으로 도입되었습니다. 코틀린은 자바에서 유래한 문법과 접근 방식을 가지고 있지만 중요한 차이점이 있습니다.

문제

주요 과제는 외부 클래스의 맥락 밖에서 존재하지 말아야 할 보조 클래스를 적절히 분리하는 것이며, 동시에 외부 클래스의 멤버에 대한 다양한 접근 수준이 필요합니다. 자바에서는 기본적으로 중첩 클래스가 inner class인 반면, 코틀린에서는 기본적으로 nested(정적)입니다.

해결책

코틀린에서는 기본적으로 다른 클래스 내에 클래스를 선언하면 정적(nested) 클래스가 생성되며, 즉 이 클래스는 외부 클래스의 멤버에 대한 접근 권한이 없습니다. 접근 권한을 얻으려면 inner 키워드를 사용해야 합니다.

코드 예:

class Outer { private val secret = "outside" class Nested { fun call() = "nested: no access to Outer.secret" } inner class Inner { fun call() = "inner: can access $secret" } }

주요 특징:

  • 중첩 클래스(class Nested)는 기본적으로 외부 클래스의 인스턴스에 대한 참조가 없습니다;
  • 내부 클래스(inner class Inner)는 참조를 가지고 있으며 외부 클래스의 멤버, 심지어 프라이빗 멤버에 접근할 수 있습니다;
  • 내부 클래스의 초기화는 외부 클래스의 인스턴스가 필요합니다.

함정이 있는 질문들.

중첩(nested) 클래스가 외부 클래스의 프라이빗 속성에 접근할 수 있습니까?

아니요, 코틀린의 중첩 클래스(기본적으로)는 정적이며 외부 클래스에 대한 참조가 없기 때문에 그 속성 및 메서드에 접근할 수 없습니다.

코틀린과 자바의 inner 클래스 간의 차이는 무엇입니까?

자바에서는 기본적으로 중첩 클래스가 정적이지 않으며 외부 클래스에 대한 참조가 있습니다. 반면 코틀린에서는 중첩 클래스가 정적이며, 오직 inner 클래스만 외부 인스턴스에 대한 참조를받습니다.

객체(object) 내에 내부 클래스를 선언할 수 있습니까?

아니요, 내부 클래스(inner)는 객체(object) 내에 선언될 수 없습니다. 객체는 인스턴스화될 수 없기 때문입니다.

일반적인 오류 및 안티 패턴

  • 외부 클래스에 대한 접근이 필요 없는 위치에 내부 클래스를 선언 — 과도한 결합도;
  • 중첩 클래스에서 외부 클래스의 멤버에 접근하려고 하면 컴파일 오류가 발생합니다;
  • 내부 클래스를 통해 외부 클래스에 대한 숨겨진 참조로 인해 메모리 누수가 발생할 수 있습니다.

실생활 예

부정적 사례

개발자가 외부 클래스의 속성을 사용하지 않는 inner 클래스를 선언:

class Container { inner class Helper { fun help() = "help" } }

장점:

외부 객체에서 클래스를 쉽게 얻을 수 있습니다.

단점:

  • 불필요한 결합도.
  • Container에 대한 숨겨진 참조로 인해 가능한 메모리 누수.

긍정적 사례

외부 클래스의 프라이빗 상태에 접근하기 위해 inner 클래스를 사용하는 경우:

class Auth { private var token: String = "" inner class TokenManager { fun updateToken(new: String) { token = new } } }

장점:

  • 프라이빗 속성에 대한 접근을 완전히 제어합니다;
  • 캡슐화 보호.

단점:

  • 테스트 가능성을 복잡하게 만듭니다;
  • 외부 클래스에 대한 종속성이 없는 경우 피하는 것이 좋습니다.