위임 객체가 재정의하는 클래스의 인스턴스이거나(finalsealed의 클래스의 경우) 혹은 재정의할 수 있는 Java 기본 메서드인(openabstract 클래스의 경우) 위임을 보고합니다.

특히 상속 계층 구조가 깊은 경우에 까다로운 버그를 일으킬 수 있어 Kotlin 위임은 Java 기본 메서드를 재정의하지 않도록 설계되었습니다.

예:


// Base.java:
public interface Base {
  default void print() {
    System.out.println("Base");
  }
}

// BaseImpl.kt:
class BaseImpl : Base {
  override fun print() {
    println("BaseImpl")
  }
}

// Main.kt:
fun main() {
  val inherited = BaseImpl()
  val delegated = object : Base by inherited {}
  inherited.print() // Outputs: BaseImpl
  delegated.print() // Outputs: Base
}

개발자들은 일반적으로 위임자에서 재정의된 기본 메서드를 포함한 모든 메서드가 포워드되기를 기대합니다. 그러나 Java 기본 메서드가 호출되고, 예기치 않은 결과를 야기할 수 있습니다.

빠른 수정 중 하나는 Java 기본 메서드의 구현을 위임 객체로 위임하여 재정의합니다.


// Main.kt:
fun main() {
  val inherited = BaseImpl()
  val delegated = object : Base by inherited {
    override fun print() {
      inherited.print()
    }
  }
  inherited.print() // 출력: BaseImpl
  delegated.print() // 출력: BaseImpl
}

다른 빠른 수정은 명시적으로 Java 기본 메서드의 구현을 상위 클래스에 위임하여 재정의합니다.


// Main.kt:
fun main() {
  val inherited = BaseImpl()
  val delegated = object : Base by inherited {
    override fun print() {
      super.print()
    }
  }
  inherited.print() // Outputs: BaseImpl
  delegated.print() // Outputs: Base
}

2025.1에서 추가