如何理解这段scala代码?
How to understand this scala code?
scala 代码:
trait Action{
def doAction
}
trait BeforeAfterOfAction extends Action{
abstract override def doAction: Unit ={
println("before")
super.doAction
println("after")
}
}
class Work extends Action{
override def doAction = println("working....")
}
object Test{
def main(args: Array[String]) {
val work = new Work with BeforeAfterOfAction
work.doAction
}
}
结果是:
before
working....
after
我认为它应该只打印“working....
”,但为什么不呢?
你能解释一下过程细节吗?
当您编写 new Work with BeforeAfterOfAction
时,您正在使用特征的 可堆叠行为 。摘自Programming in Scala:
Traits let you modify the methods of a class, and they do so in a way
that allows you to stack those modifications with each other.
你可以详细阅读here。
编辑
为了进一步解释,当您键入:
new Work with BeforeAfterOfAction
您实际上是在创建一个等同于以下 class 定义的混入:
class MyWork extends Work with BeforeAfterOfAction
现在 MyWork
class 的线性化如下:
MyWork -> BeforeAfterOfAction -> Work -> Action -> AnyRef -> Any
当您调用 new MyWork().doAction
(其中 new MyWork()
等同于 new Work with BeforeAfterOfAction
)时,它会从 BeforeAfterOfAction
调用 doAction
,因为 MyWork
没有 doAction
方法。
有趣的部分出现在 BeforeAfterOfAction
的 doAction
中遇到 super.doAction
。当遇到 super
时,从线性化的第一个右边开始选择 doAction
。在这种情况下是 Work
中的 doAction
。因此,您会看到如下输出:
before
working....
after
您可以从 this link.
阅读更多关于线性化的信息
考虑以下因素:
val x = new A with B with C
x.meth()
x
的这个实例是特征(或 classes)A
、B
和 C
的混合。当调用方法 meth()
时,编译器将首先查看 C
以查看它是否定义了该方法。如果未找到,它将在 B
中查找,最后在 A
.
中查找
在你的例子中:
val work = new Work with BeforeAfterOfAction
work.doAction
...方法 doAction
在 BeforeAfterOfAction
中找到,因此这就是被执行的方法。但在该方法中是对 super.doAction
的调用。 BeforeAfterOfAction
的超class是什么?当特征混合时,它是它之前的任何东西。
因此,编译器首先查看Work
,看看是否在那里定义了doAction
方法。既然如此,那就是被执行的。
scala 代码:
trait Action{
def doAction
}
trait BeforeAfterOfAction extends Action{
abstract override def doAction: Unit ={
println("before")
super.doAction
println("after")
}
}
class Work extends Action{
override def doAction = println("working....")
}
object Test{
def main(args: Array[String]) {
val work = new Work with BeforeAfterOfAction
work.doAction
}
}
结果是:
before
working....
after
我认为它应该只打印“working....
”,但为什么不呢?
你能解释一下过程细节吗?
当您编写 new Work with BeforeAfterOfAction
时,您正在使用特征的 可堆叠行为 。摘自Programming in Scala:
Traits let you modify the methods of a class, and they do so in a way that allows you to stack those modifications with each other.
你可以详细阅读here。
编辑
为了进一步解释,当您键入:
new Work with BeforeAfterOfAction
您实际上是在创建一个等同于以下 class 定义的混入:
class MyWork extends Work with BeforeAfterOfAction
现在 MyWork
class 的线性化如下:
MyWork -> BeforeAfterOfAction -> Work -> Action -> AnyRef -> Any
当您调用 new MyWork().doAction
(其中 new MyWork()
等同于 new Work with BeforeAfterOfAction
)时,它会从 BeforeAfterOfAction
调用 doAction
,因为 MyWork
没有 doAction
方法。
有趣的部分出现在 BeforeAfterOfAction
的 doAction
中遇到 super.doAction
。当遇到 super
时,从线性化的第一个右边开始选择 doAction
。在这种情况下是 Work
中的 doAction
。因此,您会看到如下输出:
before
working....
after
您可以从 this link.
阅读更多关于线性化的信息考虑以下因素:
val x = new A with B with C
x.meth()
x
的这个实例是特征(或 classes)A
、B
和 C
的混合。当调用方法 meth()
时,编译器将首先查看 C
以查看它是否定义了该方法。如果未找到,它将在 B
中查找,最后在 A
.
在你的例子中:
val work = new Work with BeforeAfterOfAction
work.doAction
...方法 doAction
在 BeforeAfterOfAction
中找到,因此这就是被执行的方法。但在该方法中是对 super.doAction
的调用。 BeforeAfterOfAction
的超class是什么?当特征混合时,它是它之前的任何东西。
因此,编译器首先查看Work
,看看是否在那里定义了doAction
方法。既然如此,那就是被执行的。