2017-01-03 6 views
1

У меня есть неизменный контейнер-класс.Ссылка внутренний класс от конструктора

class Foo[+T](val arg: T) { 
    // ... 
} 

Я хочу создать подкласс Foo, который имеет внутренний объект в качестве аргумента.

class Bar extends Foo[this.Inner.type](this.Inner) { 
    object Inner { 
    // ... 
    } 
    // ... 
} 

Я хотел бы, чтобы это был внутренний объект (а не отдельные один), потому что я нужен доступ к конфиденциальным данным в Bar. Тем не менее, когда я пытаюсь скомпилировать этот код, я получаю:

Example.scala:6: error: this can be used only in a class, object, or 
class Bar extends Foo[this.Inner.type](this.Inner) { 
        ^
Example.scala:6: error: this can be used only in a class, object, or template 
class Bar extends Foo[this.Inner.type](this.Inner) {template 
            ^

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

EDITED

В ответ на некоторые замечания, я полагаю, что я должен дать еще несколько особенностей. Мой класс Foo фактически специализирован как Foo[+T <: SomeAbstractClass] и имеет несколько операций, определенных на нем, которые работают с экземплярами SomeAbstractClass. Я хочу создать подкласс Bar, который ведет себя как Foo и его базовый SomeAbstractClass. Поскольку у меня не может быть Bar наследовать от обоих классов, я понял, что внутренний объект был следующим лучшим. Действительно, я хочу конкретно указать Bar и Inner, которые ведут себя как контейнер Foo и элемент SomeAbstractClass, и которые имеют полный доступ к частным переменным друг друга.

+0

* Я хотел бы, чтобы это было внутренний объект (а не отдельный один), потому что я нужен доступ к закрытым данным в баре * Можете ли вы привести пример того, что именно это вы хотите сделать? Для меня это похоже на проблему XY. –

+0

@YuvalItzchakov Я добавил дополнительный абзац, немного более конкретный. Это вообще помогает? –

ответ

0

wheaties' answer объясняет, почему это не может быть сделано так, как я хотел это сделать, но я решил, что опубликую решение, которое получило такой же эффект для меня. Я закончил писать внешний класс, который содержит как Bar, так и Inner, которые могут свободно взаимодействовать с правомерными модификаторами доступа к переменным.

class BarContainer { 
    object Bar extends Foo[Inner.type](this.Inner) { 
    // Any private fields should be declared private[BarContainer] 
    // ... 
    } 
    object Inner { 
    Bar.x = 3 
    // ... 
    } 
} 
1

То, что вы пытаетесь сделать, не может быть выполнено из-за характера, зависящего от пути вашего внутреннего object. То есть, каждый раз, когда вы делаете следующее:

val obj1 = new Bar(...){ 
    def lala(inner: Inner) = ... 
} 
val obj2 = new Bar(...) 

obj1.lala(obj2.Inner) //won't compile!! 

фактический Inner объект заново. Он не будет компилироваться, потому что Inner на obj1 не то же самое Inner на obj2. Они не одного типа!

Следовательно, вы пытаетесь сделать ссылку на определение чего-либо прежде, чем оно может быть полностью охвачено и определено. Это одна из причин, по которой компилятор собирается жаловаться.

+0

Хм ... это имеет смысл. Но тогда есть ли какое-то обходное решение, которое получило бы аналогичный результат? Я бы хотел, чтобы «Бар» и «Внутренний» имели частный доступ друг к другу, даже если они не внутри друг друга. –

+0

Нет, не совсем. – wheaties

 Смежные вопросы

  • Нет связанных вопросов^_^