我阅读了Scala中编程的section,其中引入了abstract override
,但我仍然对这些修饰符的加入所表示的确切含义感到困惑。使用这些修饰符的代码片段粘贴在下面:
trait Doubling extends IntQueue {
abstract override def put(x: Int) { super.put(2 * x) }
}
特别是,我对abstract
在这种情况下的目的感到困惑,以及为什么我们无法使用override
关键字实现预期的结果。如果我们没有包含对super
的来电,我们是否需要关键字abstract
?为什么或者为什么不?我正在寻找这个关键字组合的详细解释,因为它与可堆叠特征有关。
答案 0 :(得分:20)
原因是基类方法是 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) }
所以 - 您需要将方法标记为abstract
。
这是&#34;另一方&#34;等式:如果方法确实有实现,那么就没有必要将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
答案 1 :(得分:8)
这个想法是它是一个不完整的覆盖 - 你仍然希望最终具体实现特征提供该方法,即使你正在修改这个假设方法的行为。换句话说,您覆盖的方法不是一个完全独立的实现。它提供了与Python中method decorator类似的效果。
据我所知,特征上的方法是abstract override
当且仅当它调用super
时,它会破坏封装以期望代码的客户端检查实现知道它的方法需要具体实现。因此,您必须将其标记为abstract override
以完全定义界面。
答案 2 :(得分:2)
late binding in scala traits个帖子的一部分;提供了非常明确的解释;提供了逐字逐句(请阅读full post了解更多信息):
抽象基类提供了public static void start() {
int times = Integer.parseInt(n2sInput.getText());
for (int i = 0 ; i < times;i++) {
yourList.add(new Random().nextInt(2000) - 1000);
}
}
方法的实现。这很好,因为最左边的特征调用此方法。如果基类的方法是抽象的,会发生什么?
requestApproval
如果我们更改此内容,我们会从编译器中收到一条相当奇怪的消息:
错误:访问类abstract class ApprovalRequest {
def requestApproval()
}
中的方法requestApproval
从超级。除非被成员覆盖,否则它可能不是抽象的
声明ApprovalRequest
和abstract
override
和abstract
的组合告诉编译器该方法的最终实现将由混合特性的类提供。如果我们将abstract关键字添加到方法中,我们就不能再使用override
的匿名实现了。无法创建该对象,因为抽象覆盖方法将查找ApprovalRequest
的实现,而没有一个。{1}}。相反,我们必须创建一个扩展requestApproval
并实现ApprovalRequest
的新类。然后我们将特征混合到该类的实例中。
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