В Scala я видел конструкции
trait T extends S
и
trait T { this: S =>
используемый для достижения подобных вещей (а именно, что абстрактные методы в S
должен быть определен, прежде чем экземпляр может быть создан). Каково различие между ними? Почему Вы использовали бы один по другому?
Я бы использовал самотипы для управления зависимостями: эта черта требует добавления другой черты. И я бы использовал наследование для уточнения другой черты. или интерфейс.
В качестве примера:
trait FooService
trait FooRemoting { this : FooService => }
trait FooPersistence { this : FooService => }
object Services extends FooService with FooRemoting with FooPersistence
Теперь, если бы FooRemoting и FooPersistence унаследовали бы от FooService, а у FooService есть члены и методы, как бы выглядели Services?
В то время как для наследования у нас было бы что-то вроде :
trait Iterator[T] {
def hasNext : boolean
def next : T
}
trait InfiniteIterator[T] extends Iterator[T] {
def hasNext = true
}
Аннотации собственного типа позволяют выразить циклические зависимости. Например:
trait A extends B
trait B { self: A => }
Это невозможно при простом наследовании.
Задав вопрос, я наткнулся на следующие сообщения:
Спирос Цавеллас говорит об использовании черты характера в качестве общедоступного интерфейса и личности type в качестве помощника, который должен быть добавлен классом реализации.
В заключение, если мы хотим переместить реализации методов внутри трейтов , мы рискуем загрязнить интерфейс этих трейтов абстрактными методами , которые поддерживают реализация конкретных методов и не связаны с основной обязанностью свойства . Решение этой проблемы состоит в том, чтобы переместить эти абстрактные методы в другие черты и объединить черты вместе, используя аннотации собственного типа и множественное наследование.
Например:
trait PublicInterface { this: HelperTrait =>
// Uses helperMethod
}
trait HelperTrait {
def helperMethod = // ...
}
class ImplementationClass extends PublicInterface with HelperTrait
Путеводитель по Scala обсуждает использование аннотаций собственного типа с элементами абстрактного типа - по-видимому, невозможно расширить
член абстрактного типа (?)