2017-09-24 25 views
4

몇 가지 비슷한 질문을 본 적이 있지만 위임이 인터페이스로 제한되는 이유는 무엇입니까?kotlin에서 인터페이스 만 위임 할 수있는 이유는 무엇입니까?

사실 실제로 우리는 실제로 인터페이스가 전혀없는 것을 가지고 있습니다. 그것은 거의 구현되지 않지만 일부 기능을 제공하거나 추상 클래스를 구현하는 클래스입니다.

강제로 인터페이스로 제한하는 근본적인 제한이 있습니까? 아니면 향후 kotlin이 제한없는 위임을 가질 것으로 기대할 수 있습니까?

이것은 상속을 사용하지 않는 컴포지션을 사용하여 클래스의 기능을 확장하려는 경우에 특히 유용합니다.

class A {} 
class B(val a: A) : A by a {} 

답변

4

인터페이스를 위임 할 때 클래스는 여전히 인터페이스를 구현합니다. 일관성을 위해 클래스를 위임 할 수 있다면 같은 방식으로 작동해야합니다. 나는.

class A(x: Int) { 
    fun foo() = x 
} 

class B(val a: A) : A by a {} 

이 작동하지 않는 것을 제외하고

class B(val a: A) : A { 
    override fun foo() = a.foo() 
} 

로 컴파일 할 필요가 :

  1. fooopen하지 않고 재정의 할 수 없습니다.

  2. A의 생성자를 호출해야합니다. class B(val a: A) : A(a.x)도 도움이되지 않습니다. x은 (는) A의 회원이 아닙니다.

  3. equalshashCode : 위임자는 무엇입니까? 어느 쪽 결정이라도 이상한 결과를 초래할 수 있습니다.

+0

1. 따라서이를 무시해서는 안됩니다. 무시할 수있는 메소드 ('open' 또는'abstact')만이 자동으로 위임되어야합니다. 2. 따라서'B'는 평상시처럼 생성자 매개 변수를 'A'까지 전달해야합니다. 3. Kotlin 제작자는 모든 인터페이스가 암시 적으로 'Any'를 확장하므로 equals, hashCode 및 toString이 있으므로 인터페이스 위임을 위해이 결정을 내려야합니다. – Jesse

+0

물론 답변 일 수도 있습니다. 하지만 "상속을 사용하지 않고 컴포지션을 사용하여 클래스의 기능을 확장"하지 마십시오. 당신은 꽤 이상한 조합의 구성과 상속을 가지고 있고,'A'에서 행동을 바꾸지 않고 (예를 들어'C'가 그것을 덮어 씌울 필요가 있다고 생각했기 때문에) 메소드를 열면'B'의 행동을 바꿀 수 있습니다. –