2010-10-28 4 views
6

Я работаю над домашним заданием для моего объектно-ориентированного класса дизайна, и у меня возникают проблемы с сопутствующими объектами Scala. Я читал в нескольких местах, что объекты-компаньоны должны иметь доступ к частным методам своего компаньона, но я не могу заставить его работать. (Как примечание, мясо задания было связано с реализацией двоичного дерева поиска, поэтому я не просто прошу ответа ...)Почему я не могу получить доступ к методам частного класса в сопутствующем объекте класса в 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: error: method helpFocusRoom cannot be accessed in Atlas.Atlas a.helpFocusRoom(newRoom);

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

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

+0

wow .. Я никогда не знал, что есть ярлык «домашняя работа» – pavanred

ответ

9

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

+1

Спасибо, что делает. Профессор сказал нам на лекции использовать вложенный путь вверх, чтобы скрыть детали реализации ... Но этот способ, похоже, имеет тот же результат (и компиляции, что является плюсом). – Shaun

5

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

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 

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