scala - trait implementation -
if have traits like:
trait {...} trait b extends a{...} trait c1 extends b{...} trait c2 extends a{...} i can write class in 2 ways (c1 , c2 add same functionality)
class concrete1 extends b c1 class concrete2 extends b c2 what variant better(efficient)?
they identical in terms of performance. if write test this:
object traits { trait { def = "apple" } trait b extends { def b = "blueberry" } trait c1 extends b { def c = "cherry" } trait c2 extends { def c = "chard" } class dessert extends b c1 { } class salad extends b c2 { } } and @ bytecode dessert , salad see
public traits$dessert(); code: 0: aload_0 1: invokespecial #29; //method java/lang/object."<init>":()v 4: aload_0 5: invokestatic #33; //method traits$a$class.$init$:(ltraits$a;)v 8: aload_0 9: invokestatic #36; //method traits$b$class.$init$:(ltraits$b;)v 12: aload_0 13: invokestatic #39; //method traits$c1$class.$init$:(ltraits$c1;)v 16: return public traits$salad(); code: 0: aload_0 1: invokespecial #29; //method java/lang/object."<init>":()v 4: aload_0 5: invokestatic #33; //method traits$a$class.$init$:(ltraits$a;)v 8: aload_0 9: invokestatic #36; //method traits$b$class.$init$:(ltraits$b;)v 12: aload_0 13: invokestatic #39; //method traits$c2$class.$init$:(ltraits$c2;)v 16: return if go , @ initializers c1 , c2, they're both empty. if @ method call c, again, it's reference 1 defined either in c1 or c2.
this happens because of way layered traits interpreted. can think of them stack: each time add "with", whole inheritance hierarchy pushed onto stack except there not added again. doesn't matter whether c2 has b or not, since class salad picked b because extends b.
Comments
Post a Comment