Различие между наследованием черты и сам вводит аннотацию

В Scala я видел конструкции

trait T extends S

и

trait T { this: S =>

используемый для достижения подобных вещей (а именно, что абстрактные методы в S должен быть определен, прежде чем экземпляр может быть создан). Каково различие между ними? Почему Вы использовали бы один по другому?

41
задан Ben Lings 8 February 2010 в 21:17
поделиться

3 ответа

Я бы использовал самотипы для управления зависимостями: эта черта требует добавления другой черты. И я бы использовал наследование для уточнения другой черты. или интерфейс.

В качестве примера:

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
}
14
ответ дан 27 November 2019 в 00:50
поделиться

Аннотации собственного типа позволяют выразить циклические зависимости. Например:

trait A extends B
trait B { self: A => }

Это невозможно при простом наследовании.

26
ответ дан 27 November 2019 в 00:50
поделиться

Задав вопрос, я наткнулся на следующие сообщения:

Спирос Цавеллас говорит об использовании черты характера в качестве общедоступного интерфейса и личности type в качестве помощника, который должен быть добавлен классом реализации.

В заключение, если мы хотим переместить реализации методов внутри трейтов , мы рискуем загрязнить интерфейс этих трейтов абстрактными методами , которые поддерживают реализация конкретных методов и не связаны с основной обязанностью свойства . Решение этой проблемы состоит в том, чтобы переместить эти абстрактные методы в другие черты и объединить черты вместе, используя аннотации собственного типа и множественное наследование.

Например:

trait PublicInterface { this: HelperTrait =>
  // Uses helperMethod
}

trait HelperTrait {
  def helperMethod = // ...
}

class ImplementationClass extends PublicInterface with HelperTrait

Путеводитель по Scala обсуждает использование аннотаций собственного типа с элементами абстрактного типа - по-видимому, невозможно расширить член абстрактного типа (?)

{{ 1}}
8
ответ дан 27 November 2019 в 00:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: