Трейт в Scala (особенность)

Трейт Scala (черта) эквивалентен интерфейсу Java, но на самом деле он мощнее интерфейса.

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

В общем, классы Scala могут наследовать только один родительский класс, но когда речь идёт о трейтах (чертах), можно наследовать несколько трейтов, что приводит к множественному наследованию.

Трейт (черта) определяется аналогично классу, но использует ключевое словоtrait, как показано ниже:

Пример

trait Equal {
  def isEqual(x: Any): Boolean
  def isNotEqual(x: Any): Boolean = !isEqual(x)
}

Вышеуказанный трейт (Feature) состоит из двух методов:isEqualиisNotEqual. Метод isEqual не определяет реализацию метода, тогда как isNotEqual определяет реализацию метода. Подкласс, наследующий трейт, может реализовать нереализованный метод. Так что фактически трейт Scala (Feature) больше похож на абстрактный класс Java.

Ниже приведён полный пример трейта:

Пример

/* Имя файла: Test.scala
* автор: Example Tutorial
 * url:www.example.com
 */

trait Equal {
  def isEqual(x: Any): Boolean
  def isNotEqual(x: Any): Boolean = !isEqual(x)
}

class Point(xc: Int, yc: Int) extends Equal {
  var x: Int = xc
  var y: Int = yc
  def isEqual(obj: Any) =
    obj.isInstanceOf[Point] &&
    obj.asInstanceOf[Point].x == x
}

object Test {
   def main(args: Array[String]) {
      val p1 = new Point(2, 3)
      val p2 = new Point(2, 4)
      val p3 = new Point(3, 3)

      println(p1.isNotEqual(p2))
      println(p1.isNotEqual(p3))
      println(p1.isNotEqual(2))
   }
}

Выполнение приведенного выше кода дает следующий вывод:

$ scalac Test.scala 
$ scala Test
false
true
true

Порядок конструирования трейтов

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

Порядок выполнения конструкторов:

  • Вызывается конструктор суперкласса;
  • Конструктор трейта выполняется после конструктора суперкласса и до конструктора класса;
  • Трейты конструируются слева направо;
  • Внутри каждого трейта сначала конструируется родительский трейт;
  • Если несколько трейтов имеют общий родительский трейт, родительский трейт не будет конструироваться повторно;
  • После конструирования всех трейтов конструируется подкласс.

Порядок конструкторов является обратным по отношению к линеаризации класса. Линеаризация — это техническая спецификация, описывающая все супертипы некоторого типа.

Другие расширения