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