Самостоятельная аннотация препятствует реализации внутреннего класса. Зачем? - PullRequest
3 голосов
/ 21 ноября 2011

Учитывая абстрактные определения класса Outer и его класса Inner, я хотел бы создать конкретный класс Inner1, определенный в признаке Outer1.

abstract class Outer {
  type Inner_Tp <: Inner;
  abstract class Inner {
    self: Inner_Tp =>
  }
}

trait Outer1 {
  self: Outer =>
  protected class Inner1 extends Inner {
    self: Inner_Tp =>
  }
  def Inner1() = new Inner1()
}

Компилятор Scala преждевременнозавершает компиляцию, выдавая мне следующее сообщение об ошибке: «ошибка: не удается создать экземпляр класса Inner1, поскольку он не соответствует своему типу Outer1.this.Inner1 с Outer1.this.Inner_Tp». Почему?

В конце концов класс Inner1 определен в абстрактном контексте, являющемся его признаком Outer1.Я хотел бы отложить определение type Inner_Tp, пока черта не смешается с каким-то конкретным классом.

Ответы [ 2 ]

7 голосов
/ 21 ноября 2011

Для Inner1 самоподтверждение говорит, что он всегда будет создаваться вместе с абстрактным типом Inner_Tp. Это обещание, которое не выполняется в момент создания: тип только Inner1 вместо Inner1 with Inner_Tp.

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

trait Outer1 extends Outer {
   type Inner_Tp <: Inner1
   protected class Inner1 extends Inner

   def Inner1(): Inner_Tp
}

Я не уверен, что вы ищете, но вам, возможно, вообще не нужны самотипы (для краткости я их уже оставил).

1 голос
/ 21 ноября 2011

Поскольку self: Inner_Tp говорит о том, что ни один подтип Inner не будет разрешен для создания экземпляра, если только он не является подтипом Inner_Tp

Перезапись self => Inner_Tp в Inner1 просто повторяет ограничение, оно не удовлетворяет ему. Чтобы получить аналогичную идею, если у вас есть потомок абстрактного класса, если он не реализует абстрактный метод, вы должны снова написать, что он абстрактный. И вы не можете создать экземпляр. То же самое здесь, вы подтвердили, что Inner_Tp требуется, вы не сделали Inner_Tp доступным.

Пока Inner_Tp является абстрактным типом, вы не сможете смешивать его, и поэтому вы не сможете писать new Inner1. Возможно, вам следует ввести абстрактный метод, который создает Inners.

...