object sandbox {
class Numbers {
def price() : List[Int] = List(1,3,5,7)
def printIt(): Unit = {
price.foreach(x => print(x+ " ") )
}
}
trait DoubleIt extends Numbers {
override def price() : List[Int] ={
println("doubling")
super.price.map(x => x*2)
}
}
trait AddIt extends Numbers {
override def price() : List[Int] = {
println("adding")
super.price.map( x => x+2)
}
}
def main(args :Array[String]): Unit = {
val obj = new Numbers with DoubleIt with AddIt
obj.printIt()
}
}
//output :
adding
doubling
4 8 12 16
In the above code, price()
method from AddIt
trait executes first (from print statement).But shouldn't the value be 6 10 14 18
? Why the values are doubled before adding?
The result makes sense:
printIt
calls AddIt.price
AddIt.price
calls DoubleIt.price
, and then adds 2 to each one DoubleIt.price
calls Numbers.price
, and then dubles each one, returning List(2,6,10,14)
AddIt.price
returns List(2+2, 6+2, 10+2, 14+2)
, which is indeed the printed result The key here is understanding that indeed AddIt.price
starts before DoubleIt.price
, but it uses the result of DoubleIt.price
to create the return value, before the addition.
Your traits are stacked in the order that you declare them:
AddIt
DoubleIt
Numbers
When you run printIt, you're doing it on an AddIt, resulting in the following call chain:
AddIt.printIt
AddIt.printIt.price //here you get to print "adding"
AddIt.price.super.price //calls DoubleIt's price
DoubleIt.price //here you get to print "doubling"
DoubleIt.super.price //calls Number's price
Numbers.price //returns List(1, 3, 5, 7)
DoubleIt.super.price.map //doubles your list input
AddIt.super.price.map //adds 2 to the result
AddIt.printIt.foreach //prints the final result
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.