Вопрос по чертам - PullRequest
       17

Вопрос по чертам

7 голосов
/ 02 июля 2010

В чем разница между следующими двумя?

1 #

trait B extends A {

}

2 #

trait B { self: A =>

}

где A - абстрактный класс.

>> РЕДАКТИРОВАТЬ:

Пожалуйста, объясните относительно следующего примера Duck s с подключаемым поведением полета и кряканья:

abstract class Duck {
  def fly(): Unit
  def quack(): Unit
  def swim() {
    println("Woodoowoodoowoodoo...")
  }
}

trait FlyingWithWings extends Duck {
  override def fly() {
    println("Me can fliez! :D")
  }
}

trait FlyingNoWay { self: Duck =>
  def fly() {
    println("Me cannot fliez! :(")
  }
}

trait Quack extends Duck {
  override def quack() {
    println("Quack! Quack!")
  }
}

trait MuteQuack { self: Duck =>
  def quack() {
    println("<< Silence >>")
  }
}

class MallardDuck extends Duck with FlyingWithWings with MuteQuack

object Main {
  def main(args: Array[String]) {
    val duck = new MallardDuck
    duck.fly()
    duck.quack()
  }
}

Выход:

я могу флиз! : D
<< Тишина >>

Ответы [ 2 ]

5 голосов
/ 02 июля 2010

Во втором случае B не может использоваться в местах, где ожидается A, он просто предназначен для «привязки» к определенному A. Так, например, в первом случае A может быть абстрактным, а B может реализовывать недостающие методы, что делает его инстанцируемым типом. Это невозможно во втором случае, вам нужен «полный А», и только тогда вы добавите некоторые функции.

Таким образом, вы могли бы подумать об отношении «вписывается в ...» вместо отношения «является ...».

1 голос
/ 02 июля 2010

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

...