Как ссылаться на внешний объект из внутреннего класса в Scala

Рассмотрим этот код (который является типом безопасных единиц):

abstract class UnitsZone {
 type ConcreteUnit <: AbstractUnit
 abstract class AbstractUnit(val qty: Int) {
 SOME_ABSTRACT_MEMBERS
 def +(that: ConcreteUnit): ConcreteUnit = POINT_OF_INTEREST.apply(this.qty + that.qty)
 def apply(param: Int) = SOME_IMPLEMENTATION
 }
 def apply(qty: Int): ConcreteUnit
}
object Imperial extends UnitsZone {
 type ConcreteUnit = Pound
 class Pound(override val qty: Int) extends AbstractUnit(qty) {
 CONCRETE_MEMBERS_HERE
 }
 def apply(qty: Int) = new Pound(qty)
}

Чтобы сделать все это, мне нужно вызвать метод apply внешнего объекта относительно наследования (помеченный как POINT_OF_INTEREST в приведенном выше коде). Имея это в виду, я осмелюсь задать несколько вопросов:

  • Есть ли способ сделать это?
  • Если есть много, какие плюсы и минусы для каждого из них?
  • Если вы считаете, что все это неправильно, каков ваш правильный способ реализовать такую ​​функциональность?
2 ответа

Используйте собственную ссылку:

abstract class UnitsZone {
 outer =>
 type ConcreteUnit <: AbstractUnit
 ...
 abstract class AbstractUnit(val qty: Int) {
 def +(that: ConcreteUnit): ConcreteUnit = outer.apply(this.qty + that.qty)
 ...
 }
}

См. главу 17. Self-ссылки учебника SO Scala для получения дополнительной информации о том, что еще может сделать эта конструкция.


Так же, как Java,

class Foo {
 val foot = 0
 class Bar {
 val bart = Foo.this.foot
 }
}

или Scala,

class Foo { self =>
 val foot = 0
 class Bar {
 val bart = self.foot
 }
}

licensed under cc by-sa 3.0 with attribution.