프로그래밍시니어 Kotlin 개발자

Kotlin에서 'super' 키워드는 어떻게 작동하며 Java에서의 사용과 어떤 차이가 있습니까? 다중 인터페이스 구현에서 모호성이 발생할 경우는 어떤 경우이며, 이를 어떻게 해결합니까?

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

답변

Kotlin에서 super 키워드는 슈퍼 클래스 또는 구현된 인터페이스의 메소드 또는 속성 구현에 접근하는 데 사용됩니다. Java와 달리, Kotlin은 어떤 인터페이스 또는 클래스를 통해 메소드 구현을 호출할지를 명시적으로 지정할 수 있으므로, 동일한 메소드를 가진 여러 인터페이스 간의 '충돌'이 중요하게 됩니다.

특징: 클래스가 동일한 시그니처를 가진 메소드를 정의하는 여러 인터페이스를 구현하고 기본 구현이 있을 경우, 어떤 구현을 사용할지를 명시적으로 지정해야 합니다.

예시:

interface A { fun foo() = println("A") } interface B { fun foo() = println("B") } class C : A, B { override fun foo() { super<A>.foo() // 명시적으로 A.foo를 호출 super<B>.foo() // 명시적으로 B.foo를 호출 } }

이것은 Java에서 직접 지원되지 않습니다(Java는 인터페이스가 메소드 구현을 가질 수 없도록 허용하지 않으며, Java 8에서도 메커니즘이 다릅니다).

함정 질문

"Kotlin에서 상속의 여러 수준을 통해 슈퍼 클래스의 메소드 구현에 접근할 수 있습니까?"

  • 일반적인 실수: 중간 클래스인 super<Intermediate>.foo()를 통해 구현에 접근할 수 있다고 생각하지만, 이는 사실이 아닙니다 — 직접적인 슈퍼 클래스나 이 메소드를 직접 구현하는 인터페이스에만 접근할 수 있습니다.

예시:

open class Base { open fun foo() = println("Base") } open class Mid : Base() { override fun foo() { println("Mid"); super.foo() } } class Child: Mid() { override fun foo() { super.foo() // Mid.foo()를 호출 // super<Base>.foo() — 컴파일 오류 } }

주제의 미세한 차이로 인한 실제 오류 예시


이야기

큰 프로젝트에서 인터페이스 LoggerAuditor는 모두 메소드 record()를 정의했습니다. 두 인터페이스를 모두 상속하는 클래스를 구현할 때, 프로그래머가 명시적으로 record()를 재정의하지 않았습니다. 그 결과 "Class must override public open fun record()"라는 컴파일 오류가 발생했습니다. 메소드를 수동으로 구현하고 해당 인터페이스로 명시적으로 위임해야 했습니다.


이야기

여러 중간 레이어를 통해 슈퍼 클래스의 구현된 메소드를 호출하려 할 때(super<Base>.foo() 등), 컴파일 오류가 발생했습니다. 개발자는 Kotlin의 제한을 알지 못해 왜 직접 호출이 불가능한지 이해할 수 없었습니다.


이야기

API가 업데이트된 후, 한 인터페이스가 다른 인터페이스와 일치하는 기본 함수 구현을 추가했습니다. 이전 코드는 구현 충돌로 인해 더 이상 컴파일되지 않았습니다 — 충돌을 명시적으로 해결하고, 자신의 내부에서 어떤 슈퍼 인터페이스의 구현을 호출할 것인지를 선택해야 했습니다.