8. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
9. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
10. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
11. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
12. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
13. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
14. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
15. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
16. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
17. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
scala> Foo.d
18. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
scala> Foo.d
d evaluated
res4: String = result of d
19. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
scala> Foo.d
d evaluated
res4: String = result of d
scala> Foo.d
20. object Foo {
val v: String = {
println("v evaluated")
"result of v"
}
lazy val lv: String = {
println("lv evaluated")
"result of lv"
}
def d: String = {
println("d evaluated")
"result of d"
}
}
scala> Foo
v evaluated
res0: Foo.type = Foo$@32f96bba
scala> Foo.v
res1: String = result of v
scala> Foo.lv
lv evaluated
res2: String = result of lv
scala> Foo.lv
res3: String = result of lv
scala> Foo.d
d evaluated
res4: String = result of d
scala> Foo.d
d evaluated
res5: String = result of d
21. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
22. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
23. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
24. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
25. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
26. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
Only when parent Val is
not implemented
27. VARIABLE OVERRIDES IN INHERITANCE AND POLYMORPHISM
VAL
LAZY VAL
DEF
LAZY VAL VAL DEF
Overrides
Variable
Only when parent Val is
not implemented
Can Not Be Abstract
28. abstract class A {
val v: String
lazy val lv: String
def d: String
}
29. abstract class A {
val v: String
lazy val lv: String
def d: String
}
Can Not Be Abstract
30. abstract class A {
val v: String
lazy val lv: String = "value of lv in A"
def d: String
}
31. abstract class A {
val v: String
lazy val lv: String = "value of lv in A"
def d: String
}
class B extends A {
lazy val v: String = "value of v"
override lazy val lv: String = "value of lv"
lazy val d: String = "value of d"
}
32. abstract class A {
val v: String
lazy val lv: String = "value of lv in A"
def d: String
}
class B extends A {
lazy val v: String = "value of v"
override lazy val lv: String = "value of lv"
lazy val d: String = "value of d"
}
class C extends A {
val v: String = "value of v"
override lazy val lv: String = "value of lv"
val d: String = "value of d"
}
33. abstract class A {
val v: String
lazy val lv: String = "value of lv in A"
def d: String
}
class B extends A {
lazy val v: String = "value of v"
override lazy val lv: String = "value of lv"
lazy val d: String = "value of d"
}
class C extends A {
val v: String = "value of v"
override lazy val lv: String = "value of lv"
val d: String = "value of d"
}
class D extends A {
val v: String = "value of v"
override lazy val lv: String = "value of lv"
def d: String = "value of d"
}
34. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
35. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
36. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = hello, dad
37. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = hello, dad
scala> c.resultB
res1: String = hello, null
38. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = hello, dad
scala> c.resultB
res1: String = hello, null
scala> c.resultA
res2: String = null, null
39. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = C: hello, dad
scala> c.resultB
res1: String = B: hello, null
scala> c.resultA
res2: String = null, null
40. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultC
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultA
res2: String = hello, dad
41. INITIALIZATION ORDERS IN OVERRIDES
▸ Superclasses are fully initialized before subclasses.
▸ Otherwise, in declaration order
▸ When a `val` is overriden, it is not initialized more than once.
42. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultA
res0: String = null, null
43. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultA
res0: String = null, null
scala> c.resultB
res1: String = hello, null
44. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@7cfb4736
scala> c.resultA
res0: String = null, null
scala> c.resultB
res1: String = hello, null
scala> c.resultC
res2: String = hello, dad
45. abstract class D {
val c: C
val x3 = c.x1
}
class E extends D {
val c = new C
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
46. abstract class D {
val c: C
val x3 = c.x1
}
class E extends D {
val c = new C
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> new E
47. abstract class D {
val c: C
val x3 = c.x1
}
class E extends D {
val c = new C
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> new E
java.lang.NullPointerException
... 30 elided
49. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends {
val x1: String = "hello"
} with A {
val resultB = x1 + ", " + x2
}
class C extends {
override val x2: String = "dad"
} with B {
val resultC = x1 + ", " + x2
}
50. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends {
val x1: String = "hello"
} with A {
val resultB = x1 + ", " + x2
}
class C extends {
override val x2: String = "dad"
} with B {
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@22d9bc14
scala> c.resultA
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultC
res2: String = hello, dad
51. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends {
val x1: String = "hello"
} with A {
val resultB = x1 + ", " + x2
}
class C extends {
override val x2: String = "dad"
} with B {
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@22d9bc14
scala> c.resultA
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultC
res2: String = hello, dad
53. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
54. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
55. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
Only when parent Val is
not implemented
56. abstract class A {
val x1: String
val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override val x2: String = "dad"
val resultC = x1 + ", " + x2
}
abstract class A {
val x1: String
lazy val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
57. abstract class A {
val x1: String
lazy val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@2f74900b
scala> c.resultA
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultC
res2: String = hello, dad
58. abstract class A {
val x1: String
lazy val x2: String = "mom"
val resultA = x1 + ", " + x2
}
class B extends A {
lazy val x1: String = "hello"
val resultB = x1 + ", " + x2
}
class C extends B {
override lazy val x2: String = "dad"
val resultC = x1 + ", " + x2
}
scala> val c = new C
c: C = C@2f74900b
scala> c.resultA
res0: String = hello, dad
scala> c.resultB
res1: String = hello, dad
scala> c.resultC
res2: String = hello, dad