scala 的特征和来自《Scala 编程》第二版的 super 示例

标签 scala

我对队列示例的两件事感到有点困惑:

问题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:为什么具有 super 特质?

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) } 

这行Doubling方法重写了BasicInQueue的方法?如果是这样,为什么我们需要 super?为什么我们不能这样做:

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

对我来说,上面的行只会用新的 put 实现覆盖 BasicInQueue 的方法?抽象覆盖关键字仅用于运行时的某种堆栈操作,对吗?为什么我们还需要 super 呢? super 指的是什么?左边那是什么?那么对于BasicIntQueue with Doubling来说,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方法将其实际添加到队列中。

关于scala 的特征和来自《Scala 编程》第二版的 super 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6684300/

相关文章:

scala - 是否可以改进 Scala 中部分应用类型的类型推断?

scala - 在 Scala 中是否使用上下文绑定(bind)或隐式 ev

java - Spark : Dataframe action really slow when upgraded from 2. 1.0 至 2.2.1

scala - Scala 背后的可索引数据结构便于理解

scala - scala中从Int到Double的隐式转换不起作用

scala - PartialFunction 如何处理 Scala 中的未定义值?

scala - Spark、Kryo ProtoBuf 字段的序列化问题

scala - 覆盖 sbt 依赖解析机制(并防止 jar hell)

scala - 在Scala/Slick中,如何重构代码(响应拦截)?

Scala for-comprehension 返回有序映射