0
votes

I asked the following question if a variable is defined in a class extends a trait, how to use it in the trait?

And one of the answer is as below:

trait T1 { def a: String; def x = a.length }
class Test(val a: String) extends T1

But if only works:

  1. define a in T1 as "def a", if I use "val a" or "var a", then it doesn't work
  2. define a in Test as "val a", if I just use "a" which means default to "var a", it also doesn't work.

Why does it happen?

1
"It doesn't work" doesn't describe the error you're seeing. Always describe the actual error.Jon Skeet
Works for me: scala> trait T1 { val a: String; def x = a.length } defined trait T1 scala> class Test(val a: String) extends T1 defined class Test scala> new Test("foo").x res0: Int = 3Dima
It doesn't "default to var a" - if you write class Test(a: String) then that is not the same as class Test(var a: String). For case classes it's the same as val a but not var a.Jesper

1 Answers

2
votes

"#1" should work, as I mentioned in the comment. Regarding #2, there two things:

  1. class Test(a: String) is not the same as class Test(var a: String) (if anything, it is actually closer to val declaration, but isn't the same either, except for case classes). The latter declares a as a mutable class member, while the former just makes it an argument to the constructor, not a member of the class at all. For this reason, it fails in your case: you have to override the abstract member a of T1 in order to be able to extend it.

  2. class Test(var a: String) won't work either. This is because a is declared in T1 as def, which makes it immutable. You can override a def with a def or a val, but you cannot override it with a mutable value. If you need it to be mutable in Test, you have to declare it as a var in T1 as well.