문제

다음 코드가 있다고 가정합니다.

trait Trait1 { 
  trait Inner {
    val name = "Inner1"
  }
}

trait Trait2 {
  trait Inner {
    val name = "Inner2"
  }
}

class Foo extends Trait1 with Trait2 {
  // I want Concrete1 to be a Trait1.Inner not a Trait2.Inner
  class Concrete1 extends Inner
  val c = new Concrete1
}

object Obj {
  def main(args: Array[String]): Unit = {
    val foo = new Foo
    println(foo.c.name)
  }
}

내가 섞을 때 Trait1 그리고 Trait2, 참조 Inner 기본값으로 보인다 Inner 내가 두 번째로 혼합 한 특성의 유형; 그래서 내가 전화 할 때 Obj'에스 main 인쇄 방법 Inner2. 어떻게 참조 할 수 있습니까? Trait1.Inner 안에 Foo? 다음 세 가지 모두 컴파일러 오류를 제공합니다.

class Concrete1 extends Trait1.Inner
class Concrete1 extends Trait1$Inner
class Concrete1 extends Trait1#Inner
도움이 되었습니까?

해결책

대신에

class Concrete1 extends Inner

이것을 사용하십시오

class Concrete1 extends super[Trait1].Inner

그것은 당신이 원하는 것을 얻을 것입니다

다른 팁

템플릿 내에 두 개의 네임 스페이스가 있습니다 (템플릿은 클래스, 객체 또는 특성의 본문입니다.)

  1. 회원 : Vals, VAR 및 DEFS 및 중첩 된 물체
  2. 유형 : 유형 별명, 중첩 특성 및 중첩 클래스

여러 학부모 템플릿에서 상속 할 때이 네임 스페이스의 충돌은 클래스 선형화를 통해 해결됩니다.

당신은 당신의 상속을 다시 주문하여 원하는 부모를 수업에 가져 오거나 대체 디자인을 찾을 수 있습니다.

하나의 옵션 (특성을 침습 할 수있는 경우)은 각 내부 특성을 비유 성 이름을 가진 유형 멤버로 정의하는 것입니다.

trait Trait1 {
  type Inner1 = Inner
  trait Inner {
    val name = "Inner1"
  }
}

trait Trait2 {
  type Inner2 = Inner
  trait Inner {
    val name = "Inner2"
  }
}

class Foo extends Trait1 with Trait2 {
  class Concrete1 extends Inner1
  class Concrete2 extends Inner2
  val c1 = new Concrete1
  val c2 = new Concrete2
}

object App extends Application {
  val foo = new Foo
  println(foo.c1.name) // Inner1
  println(foo.c2.name) // Inner2
}

원래 특성 (Trait1 및 Trait2)을 침습 할 수없는 경우 유형 멤버를 정의하도록 확장 할 수 있습니다.

trait Trait1 {
  trait Inner {
    val name = "Inner1"
  }
}
trait Trait2 {
  trait Inner {
    val name = "Inner2"
  }
}

trait Trait1a extends Trait1 {
  type Inner1 = Inner
}
trait Trait2a extends Trait2 {
  type Inner2 = Inner
}

class Foo extends Trait1a with Trait2a {
  class Concrete1 extends Inner1
  class Concrete2 extends Inner2
  val c1 = new Concrete1
  val c2 = new Concrete2
}

또 다른 접근법은 중간 특성을 사용하여 첫 번째 콘크리트 클래스를 정의하는 것입니다.

trait Trait1 {
  trait Inner {
    val name = "Inner1"
  }
}
trait Trait2 {
  trait Inner {
    val name = "Inner2"
  }
}

trait FooIntermediate extends Trait1 {
  class Concrete1 extends Inner
}

class Foo extends FooIntermediate with Trait2 {
  class Concrete2 extends Inner
  val c1 = new Concrete1
  val c2 = new Concrete2
}

우선 순위가 기대되는 순서대로 특성을 주문하지 않겠습니까? 특성의 선형화는 임의적이지 않고 지정됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top