Почему я не могу получить доступ к методам частного класса в объекте-компаньоне класса в Scala? - PullRequest
6 голосов
/ 28 октября 2010

Я работаю над домашним заданием для своего класса объектно-ориентированного дизайна, и у меня возникают проблемы с сопутствующими объектами Scala.Я читал в нескольких местах, что объекты-компаньоны должны иметь доступ к закрытым методам их класса-компаньона, но я не могу заставить их работать.(Как примечание, основное назначение было связано с реализацией бинарного дерева поиска, поэтому я не просто спрашиваю ответы ...)

У меня есть объект, который должен создатьЭкземпляр моего частного класса, BstAtlas (Bst также определен в объекте Atlas, вынул его для ясности):

object Atlas {                                             
  def focusRoom(newRoom:Room,a:Atlas):Atlas = a.helpFocusRoom(newRoom);

  abstract class Atlas {
    ...
    protected def helpFocusRoom(n:Room):Atlas;
    ...
  }

  private class BstAtlas(bst:Bst) extends Atlas {
    ...
    protected def helpFocusRoom(newRoom:Room):Atlas = ...
       // uses some of bst's methods
    ...
  }
}

Но когда я иду на компиляцию, я получаю следующую ошибку:

Question23.scala: 15: ошибка: метод helpFocusRoom недоступен в Atlas.Atlas a.helpFocusRoom (newRoom);

Функция helpFocusRoom должна быть скрыта, но я не 'не знаю, как его спрятать, и у него все еще есть доступ к нему внутри объекта-компаньона.

Может кто-нибудь сказать мне, что я делаю здесь неправильно?

Ответы [ 2 ]

11 голосов
/ 28 октября 2010

Проблема в том, что классы и сопутствующие объекты не могут быть вложены таким образом. Чтобы определить сопутствующий объект, вам нужно определить класс вне тела объекта, но в том же файле.

5 голосов
/ 28 октября 2010

Сопутствующие объекты должны быть рядом с их реальным объектом, а не содержать его:

object Example {
  class C(val i: Int = C.DefaultI) { }
  object C { protected val DefaultI = 5 }
}

scala> (new Example.C).i
res0: Int = 5

scala> Example.C.DefaultI
<console>:11: error: value DefaultI cannot be accessed in object Example.C
   Example.C.DefaultI

Кроме того, вы можете изменить область действия ключевого слова protected, чтобы включить в него объект:

object Example {
  def value = (new D).hidden
  class D(val i: Int = 5) {
    protected[Example] def hidden = i*i
  }
}

scala> Example.value
res1: Int = 25

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

...