Whats wrong with the below code snippet, is this related to diamond problem ? When i try to call the function func with D's instance I am facing run time error
trait B{
def func(): Unit = {
println("Inside class B")
}
}
trait C{
def func(): Unit = {
println("Inside class C")
}
}
class D extends B with C{
}
object ABC extends App{
val ob = new D
ob.func()
}
Well, as written, B.func and C.func are unrelated, so when you do D extends B with C, it ends up having two unrelated members with the same name - thus the error.
A naive attempt to fix this, would be to add a common parent:
trait A { def func(): Unit }
trait B extends A { def func() = println("B") }
trait C extends A { def func() = println("C") }
class D extends B with C
Surprisingly, this does not compile either (which to me seems like it's a bug in the compiler 🤷), but if you just add override to the declarations (which is not required and should not make any difference), then it will:
trait A { def func(): Unit }
trait B extends A { override def func() = println("B") }
trait C extends A { override def func() = println("C") }
class D extends B with C
Update Ok, maybe, I I need to relax my rant about "bug in the compiler" a little bit, and downgrade it to "obscure and weird behavior" :) It looks like only the declaration in C needs the override in this case, B can go without ... this kinda sorta makes a little bit of sense: C's func in D overrides a concrete implementation (from B), which makes override required ... If the compiler error actually mentioned this, I would be willing to go further and downgrade "obscure and weird behvaior" to "unnecessary boilerplate requirement" :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With