프로그래밍Kotlin/Java 개발자

코틀린에서 생성자 상속은 어떻게 이루어지며, super 생성자 호출은 어떻게 작동하며, primary와 secondary 생성자를 조합할 때 어떤 주의사항이 있는지 설명하십시오. 다양한 경우의 예를 제시하고 Java와의 차이점을 설명하십시오.

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

답변

코틀린에서는 클래스에 하나의 primary constructor와 원하는 만큼의 secondary constructors가 있을 수 있습니다. Java와의 차이점은 코틀린의 primary constructor가 클래스의 헤더에 선언되어 매개변수와 수정자를 포함할 수 있다는 것입니다. Secondary 생성자는 항상 다른 secondary 생성자, primary constructor 또는 상위 클래스의 생성자(super 키워드 사용)를 호출해야 합니다.

주요 특징:

  • 상위 클래스가 필수 매개변수를 가진 primary constructor를 갖고 있다면 하위 클래스는 반드시 : super(...)를 통해 이를 명시적으로 호출해야 합니다.
  • Secondary 생성자에서는 기본 클래스가 super(...) 또는 다른 secondary/primary constructor를 통해 호출됩니다.
  • 초기화 충돌은 허용되지 않으며 모든 필드는 항상 올바르게 초기화되어야 합니다.

상속 사용 예:

open class A(val a: Int) { constructor(a: Int, str: String) : this(a) { println("Secondary in A: $str") } } class B : A { constructor(a: Int) : super(a) { println("Secondary in B") } constructor(a: Int, s: String) : super(a, s) { println("Secondary #2 in B") } }

Java와의 접근 방식 차이:

  • 코틀린에서는 상위 클래스의 생성자를 호출하지 않는 것이 불가능합니다.
  • Primary constructor는 항상 기본 매개변수를 초기화하며 암묵적일 수 있습니다.

트릭 질문

코틀린에서 자식 클래스를 만들 때, 기본 클래스에 특정 생성자만 있을 경우 상위 생성자를 명시적으로 호출하지 않을 수 있습니까?

답변: 아니요, Java와는 달리 코틀린에서는 상위 생성자를 호출하는 것이 필수이며, 이는 클래스의 "헤드"에서 또는 : super() 키워드 뒤에 명시적으로 지정해야 합니다.

오류 예시:

open class Base(val x: Int) class Derived : Base // 컴파일 오류!

주제의 세부 사항을 모르는 것 때문에 발생한 실제 오류 예


이야기

마이크로서비스 프로젝트에서 코틀린으로 마이그레이션한 후 상위 생성자의 명시적 호출을 잊어버렸습니다: 필수 매개변수를 가진 상위 클래스 생성자가 호출되지 않아 서비스가 컴파일되지 않았고, 서명 수정이 필요했습니다.


이야기

안드로이드 프로젝트에서 깊은 계층 구조(Activity → BaseActivity → CustomActivity)가 있었고, secondary constructor를 추가하면서 매개변수를 잃어버リ, 잘못된 기본 생성자가 호출되어 일부 필드가 null로 남아 런타임 중 NPE로 앱이 종료되었습니다.


이야기

오픈 소스 라이브러리 코드에서 자식 클래스의 secondary constructor가 우연히 primary constructor를 우회하여 초기화 경로가 두 개가 되는 바람에 때때로 필드가 초기화되거나 그렇지 않은 문제가 발생했습니다. 이 오류는 복잡한 버그 리포트를 통해 오랜 시간이 지나서야 발견되었습니다.