Подтвердить что ты не робот

Разница между наследованием признаков и аннотацией типа

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

trait T extends S

и

trait T { this: S =>

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

4b9b3361

Ответ 1

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

Как пример:

trait FooService

trait FooRemoting { this : FooService => }
trait FooPersistence { this : FooService => }

object Services extends FooService with FooRemoting with FooPersistence

Теперь, если FooRemoting и FooPersistence оба унаследовали бы от FooService, а у FooService есть члены и методы, как бы выглядели бы службы?

Если для наследования у нас будет что-то вроде:

trait Iterator[T] {
  def hasNext : boolean
  def next : T
}

trait InfiniteIterator[T] extends Iterator[T] {
  def hasNext = true
}

Ответ 2

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

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

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

Ответ 3

Спрашивая вопрос, я столкнулся с этими сообщениями:

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

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

Например:

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

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

class ImplementationClass extends PublicInterface with HelperTrait

Обзор Scala обсуждается с использованием аннотаций типа self с элементами абстрактного типа - по-видимому, не возможно extend абстрактный элемент типа (?)

Ответ 4

Ответ - "округлость". Но не только.

Аннотации типа Self решают для меня основную проблему наследования: то, что вы наследуете, не может использовать то, что вы есть. С типом self все становится легко.

Мой шаблон следующий и может рассматриваться как вырожденный торт:

trait A { self: X => def a = reuseme}
trait B { self: X => def b = a }
class X extends A with B { def reuseme=null }

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

Половина (если не совокупность) свернутых фреймворков Java DI за последние десять лет была посвящена этому, конечно, без ввода текста. Люди, все еще использующие JAVA в этом домене, явно теряют свое время: "SCALA ouakbar".

Ответ 5

Несмотря на то, что он не отвечает на ваш вопрос, я пытался понять аннотации самонаведения и в основном потерялся в ответах, и как-то закончил велосипедную прогулку по вариациям вашего вопроса, в котором основное внимание уделяется использованию аннотаций самонастройки для определяя зависимости.

Итак, здесь я публикую описание варианта использования, в котором хорошо иллюстрируются аннотации самостоятельного типа, а именно что-то вроде безопасного типа 'this' в качестве подтипа:

http://programming-scala.labs.oreilly.com/ch13.html#SelfTypeAnnotationsAndAbstractTypeMembers

надеясь, что было бы полезно тем, кто попадает на этот вопрос случайно (и, как и я, не успел прочитать книгу scala, прежде чем начинать исследовать:-))