Наследование одноименного метода от отличительных признаков

У меня есть трейт, который расширяет два других трейта с одинаковым именем для функции, но немного отличается внутри. Я хочу знать, как узнать, какая функция будет вызвана?

У меня есть черта B, у которой есть print(), и черта C, у которой есть print(), если я унаследую их обе следующим образом:

trait A extends B with C {
    def print()
}

каждая печать печатает что-то еще, какая печать будет вызываться?


person jack miao    schedule 25.10.2016    source источник


Ответы (3)


В конкретном случае, когда у вас есть конфликты имен, вы получите ошибку времени компиляции. Предполагая, что D является классом реализации:

class D extends A with C with B

def main(args: Array[String]): Unit = {
  val d = new D
  println(d.print())
}

Ты увидишь:

Error:(25, 9) class D inherits conflicting members:
  method print in trait B of type ()Unit  and
  method print in trait C of type ()Unit
(Note: this can be resolved by declaring an override in class D.)
  class D extends A with B with C

Однако, если мы поможем компилятору, добавив override print() к D и заставив его вызывать super.print(), он напечатает последний трейт в linage, который поддерживает метод print, т.е.:

trait A { }

trait B { def print() = println("hello") }

trait C { def print() = println("world") }

class D extends A with B with C {
  override def print(): Unit = super.print()
}

Получится "мир". Если мы поменяем местами B и C:

class D extends A with C with B {
  override def print(): Unit = super.print()
}

Мы получили бы "привет".

person Yuval Itzchakov    schedule 25.10.2016
comment
Я бы просто добавил, что вы можете быть явным: class D extends A with B with C { override def print(): Unit = super[B].print() }. - person Alexey Romanov; 25.10.2016

Одной из наиболее важных особенностей Traits в оригинальной книге Schärli, Ducassé, Nierstrasz, Black paper является разрешение конфликтов путем переименования и сокрытия. Эта функция полностью отсутствует в Traits Scala.

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

person Jörg W Mittag    schedule 25.10.2016

Компилятор Scala выдает ошибку компиляции.

Почему бы вам самому не увидеть это с помощью Scala REPL.

scala> trait B { def print(): Unit = println("B") }
defined trait B

scala> trait C { def print(): Unit = println("C") }
defined trait C

scala> trait A extends B with C { def foo = print() }
cmd11.sc:1: trait A inherits conflicting members:
  method print in trait B of type ()Unit  and
  method print in trait C of type ()Unit
(Note: this can be resolved by declaring an override in trait A.)
trait A extends B with C { def foo = print() }
      ^
Compilation Failed

Я думаю, вы можете легко понять, используя ошибку компилятора

person pamu    schedule 25.10.2016