Черты Scala и супер примеры из программирования в Scala 2-е изд - PullRequest
2 голосов
/ 13 июля 2011

Я запутался в примере очереди с двумя вещами:

Вопрос 1. Почему в методах BasicIntQueue отсутствует ключевое слово override.

Вот пример кода:

abstract class IntQueue {
  def get(): Int
  def put(x: Int)
}

import scala.collection.mutable.ArrayBuffer
class BasicIntQueue extends IntQueue {
  private val buf = new ArrayBuffer[Int]
  def get() = buf.remove()
  def put(x: Int) { buf += x }
}

Не должно ли быть:

//class BasicIntQueue ...

  override def get() = buf.remove()
  override def put(x: Int) { buf += x }

Я реализовал с переопределением, и ожидаемый результат тот же.

Вопрос 2: Почему супер в чертах?

trait Doubling extends IntQueue {
  abstract override def put(x: Int) { super.put(2 * x) }
}
class MyQueue extends BasicIntQueue with Doubling

Я пробовал это без супер ключевого слова, и это не удалось. Я нарисовал диаграмму UML, но у меня есть нечеткое объяснение, почему.

  abstract override def put(x: Int) { super.put(2 * x) } 

Эта строка метода удвоения переопределяет метод BasicInQueue? Если так, то зачем нам супер? Почему мы не можем просто сделать:

  abstract override def put(x: Int) { 2 * x } 

Для меня приведенная выше строка просто переопределит метод BasicInQueue с новой реализацией put? Ключевое слово abstract override предназначено только для манипуляций со стеком во время выполнения, верно? Зачем нам супер все равно? На что ссылается супер? Что бы это ни было слева? Так что с BasicIntQueue with Doubling, является ли ключевое слово super в Doubling ссылкой на BasicIntQueue?

Спасибо, что уделили время.

1 Ответ

6 голосов
/ 13 июля 2011

Для вопроса 1 IntQueue объявлен как абстрактный, а методы являются виртуальными. Поэтому BasicIntQueue - это не переопределение методов, а предоставление необходимых реализаций. Если бы у методов в IntQueue были тела, то BasicIntQueue понадобилось бы ключевое слово override для его методов.

В вопросе 2 super относится к методу, который переопределяет метод черты. Эта черта требует, чтобы в классе был определен метод put, но вместо полной его замены он дополняет его, удваивая значение, отправленное ему.

abstract override def put(x: Int) { 2 * x } 

не будет работать, потому что фактически ничего не помещает в очередь, фактически, поскольку функция является Unit (ничего не возвращает), она вообще ничего не делает.

abstract override def put(x: Int) { super.put(2 * x) } 

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...