在两件事上,我对队列示例有些困惑:

问题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


我尝试了没有super关键字的尝试,但失败了。我绘制了一个UML图,但是有一些模糊的原因。

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


这行方法加倍了BasicInQueue的方法?如果是这样,为什么我们需要超级?我们为什么不能这样做:

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


对我来说,上面的行会使用新的put实现覆盖BasicInQueue的方法吗?抽象的override关键字仅在运行时用于某种堆栈操作,对吗?为什么我们仍然需要超级?超级指的是什么?左边是什么?因此,对于BasicIntQueue with Doubling,加倍中的super关键字是否引用BasicIntQueue?

感谢您的时间。

最佳答案

对于问题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方法将其实际添加到队列中。

10-08 02:06