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

Почему "абстрактное переопределение" требуется не "переопределять" в одиночку в субтрайте?

Я прочитал раздел программирования в Scala, где abstract override введен, но я все еще смущен тем, что именно обозначается объединением этих модификаторы. Ниже приведен фрагмент кода, в котором используются эти модификаторы:

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

В частности, в этом случае я смущен целью abstract и почему мы не можем достичь ожидаемых результатов просто с помощью ключевого слова override. Если бы мы не включили вызов super, нам понадобилось бы ключевое слово abstract? Почему или почему нет? Я ищу подробное объяснение этого ключевого слова combo, поскольку оно относится к элементарным признакам.

4b9b3361

Ответ 1

Причина в том, что метод базового класса abstract

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

Если вы не ставите abstract по признаку, вы получите объяснение, которое вы искали:

trait Doubling extends IntQueue {
     override def put(x: Int) { super.put(2 * x) }
}
<console>:9: error: method put in class IntQueue is accessed from super. It may not be abstract unless it is overridden by a member declared `abstract' and `override'
            override def put(x: Int) { super.put(2 * x) }

Вот "другая сторона" уравнения: если методы имеют реализации, тогда нет необходимости отмечать метод trait как abstract:

 abstract class IntQueue {
    import collection.mutable._
        val q  =  Queue[Int]()
      def get(): Int = { q.dequeue() }
      def put(x: Int) = { q.enqueue(x) }
   }

Теперь нет необходимости включать abstract

 trait Doubling extends IntQueue {
        /* Look Ma! no abstract here ! */   override def put(x: Int) { super.put(2 * x) }
      }
defined trait Doubling

Ответ 2

Идея состоит в том, что это неполное переопределение - вы все еще хотите потребовать, в конечном итоге, конкретной реализации этой функции, чтобы обеспечить этот метод, даже если вы изменяете поведение гипотетического метода. Другими словами, метод, который вы переопределяете, не является полной автономной реализацией. Это дает такой же эффект, как

Ответ 3

Часть поздняя привязка в сообщениях scala; дает очень четкое объяснение; приведенный ниже (читайте полный пост для получения дополнительной информации):

Абстрактный базовый класс обеспечил реализацию метода requestApproval. Это хорошо, так как самый левый признак вызывает этот метод. Что произойдет, если метод базовых классов является абстрактным?

abstract class ApprovalRequest {
  def requestApproval()
}

Если мы изменим это, мы получим довольно нечетное сообщение от компилятора: error: метод requestApproval в классе. Доступ к RequestRequest от супер. Он может быть не абстрактным, если он не будет отменен членом объявлено abstract' and override ' Комбинация абстрактного и переопределения сообщает компилятору, что конечная реализация метода будет предоставляться классом, смешивающим признак. Если мы добавим ключевое слово abstract к методам, мы больше не сможем использовать нашу анонимную реализацию CertificateRequest. Этот объект не может быть создан, поскольку методы абстрактного переопределения будут искать реализацию requestApproval и не существует. Вместо этого мы должны создать новый класс, который расширяет RequestRequest и реализует requestApproval. Затем мы смешиваем черты с экземпляром этого класса.

class ApprovalDelegate extends ApprovalRequest {
  override def requestApproval() {
    println("and now we play the waiting game")
  }
}

val adCampaign = new ApprovalDelegate with MarketingApprovalRequest
   with FinanceApprovalRequest with ExecutiveApprovalRequest

Что теперь даст выход

requesting approaval from executives requesting approval from Finance requesting approval from Marketing and now we play the waiting game