Конфиденциальность внутренних классов и доступность из подтипов внешнего типа - PullRequest
1 голос
/ 28 ноября 2011

У меня проблемы с закрытой аннотацией методов и конструкторов внутреннего класса. Пока это работает как положено:

trait A {
  protected def lala = ()
}

trait B extends A {
  lala
}

Следующее не:

trait A {
  class Lala protected()
}

trait B extends A {
   new Lala
}

Также не делает это:

trait A {
  class Lala private[A]()
}

trait B extends A {
  new Lala
}

Единственный способ обойти это примерно так:

object Screwed {
  trait A {
    class Lala private[Screwed]()
  }

  trait B extends A {
    new Lala
  }
}

Действительно ли Scala здесь не в состоянии обеспечить четкий механизм или я что-то упустил? Мое предположение было бы, что это должно быть private[this.type], но Скалак не хочет глотать это вообще ...

Ответы [ 3 ]

6 голосов
/ 28 ноября 2011

Ну,

trait A {
  class Lala protected()
  new Lala
}

тоже не компилируется.Сообщение об ошибке кажется довольно разумным:

 error: constructor Lala in class Lala cannot be accessed in trait A
 Access to protected constructor Lala not permitted because
 enclosing class trait A in object $iw is not a subclass of
 class Lala in trait A where target is defined

Защищенный доступ означает, что вы можете получить доступ к этому конструктору только из этого класса или подклассов.Вы пытаетесь назвать это из черты вложения.Одна вещь, которую вы можете сделать, это:

trait B extends A {
  class Gaga extends Lala
  new Gaga
}

Я бы не ожидал, что ваш третий пример будет компилироваться по тем же причинам.

Также обратите внимание на разницу между защищенным конструктором и protected class.Так, например:

trait A {
  protected class P
  class U  // unprotected
}

class B extends A {
  new P  // OK
  new U  // OK
}

val b = new B
new b.P  // error
new b.U  // OK
1 голос
/ 28 ноября 2011

Это также работает с желаемой видимостью (Lala может быть создан только из A или подтипов A).

trait A {
   class Lala private[A]()
   protected def newLala = new Lala
}

trait B extends A {
   newLala
}

Интересно, какова цель чего-то вроде protected[A] если это не сработает в этом случае.

0 голосов
/ 28 ноября 2011

защищенный должен работать наверняка, какую ошибку вы получаете?для частных, определяемая вами область действия управляет их видимостью (поэтому в черте A, если вы даете видимость A, она явно не видна в B).В последнем примере вы задали область действия как Screwed, чтобы все, что находится внутри Screwed, могло видеть приватный класс.Кстати, я предпочитаю писать модификаторы доступа в первую очередь в строке кода, чтобы упростить чтение

какую версию scala вы используете и что вы подразумеваете под «не работает»?

НТН!

...