Отличная книга Программирование в Scala имеет довольно хорошее объяснение :
class Outer {
class Inner
}
В Scala внутренний класс адресуется с помощью выражения Outer#Inner
вместо Outer.Inner
в Java,Синтаксис .
зарезервирован для объектов.Например, представьте, что вы создаете два объекта типа Outer
, например:
val o1 = new Outer
val o2 = new Outer
Здесь o1.Inner
и o2.Inner
- это два зависимых от пути типа (и это разные типы).Оба эти типа соответствуют (являются подтипами) более общего типа Outer#Inner
, который представляет класс Inner с произвольным внешним объектом типа Outer.Напротив, тип o1.Inner
относится к классу Inner с определенным внешним объектом (тот, на который ссылается o1
).Аналогично, тип o2.Inner
относится к классу Inner с другим конкретным внешним объектом (объект, на который ссылается o2
).
В Scala, как и в Java, экземпляры внутреннего класса содержат ссылку на вмещающий объект.экземпляр внешнего класса.Это позволяет внутреннему классу, например, получать доступ к членам своего внешнего класса.Таким образом, вы не можете создать экземпляр внутреннего класса, не указав каким-либо образом экземпляр внешнего класса.Один из способов сделать это - создать экземпляр внутреннего класса внутри тела внешнего класса.В этом случае будет использован текущий экземпляр внешнего класса (на который есть ссылка).Другой способ - использовать тип, зависящий от пути.Например, поскольку тип o1.Inner называет конкретный внешний объект, вы можете создать его экземпляр:
scala> new o1.Inner
res1: o1.Inner = Outer$Inner@13727f
Результирующий внутренний объект будет содержать ссылку на свой внешний объект, объект, на который ссылается o1
.В отличие от этого, поскольку тип Outer#Inner
не называет ни одного конкретного экземпляра Outer
, вы не можете создать его экземпляр:
scala> new Outer#Inner
<console>:6: error: Outer is not a legal prefix for
a constructor
new Outer#Inner
^