Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there something wrong with an abstract value used in trait in scala?

Tags:

scala

traits

I have

trait Invoker {   val method: Method } 

Intellij IDEA code inspection is warning me that "Abstract value used in trait". Everything compiles fine. Is there something wrong with having an abstract value in a trait? If so, how should I specify that all extenders of the trait must define a method property?

like image 914
pondermatic Avatar asked Oct 21 '11 07:10

pondermatic


People also ask

Can an abstract class extend a trait?

A class can extend only one abstract class, but it can implement multiple traits, so using traits is more flexible.

What is the difference between a trait and an abstract class in scala?

Trait supports multiple inheritance. Abstract Class supports single inheritance only. Trait can be added to an object instance. Abstract class cannot be added to an object instance.

Which is true for abstract classes in scala?

In Scala, an abstract class is constructed using the abstract keyword. It contains both abstract and non-abstract methods and cannot support multiple inheritances. A class can extend only one abstract class. The abstract methods of abstract class are those methods which do not contain any implementation.

Can scala trait have variables?

In scala, trait is a collection of abstract and non-abstract methods. You can create trait that can have all abstract methods or some abstract and some non-abstract methods. A variable that is declared either by using val or var keyword in a trait get internally implemented in the class that implements the trait.


1 Answers

What is meant by this is the following weirdness:

trait A {   val i: String   def j: String }  class C extends A {   println ("val i = " + i)   println ("def j = " + j)    val i = "i"   def j = "j" }  val c = new C // prints // val i = null // def j = j 

So, as you can see i is initialised to it default value (null for AnyRef) before it is finally overridden by the constructor in C. (def declarations are re-referenced immediately.)

To avoid this one would have to put the val initialisations to the beginning of the constructor, if possible.


Additional weirdness (and how to solve it) in the following case

Consider

trait A {   val i: String   def j: String }  abstract class D extends A {   println ("val i = " + i)   println ("def j = " + j) }  class C extends D {   val i = "i"   def j = "j" } val c = new C // prints // val i = null // def j = null 

Now we seem to be out of luck; it looks as if there is no chance for us to initialise val i and def j before our superclass D tries to print them. In order to solve this problem, we must use Early definitions (§5.1.6 Scala reference):

class C extends {   val i = "i"   def j = "j" } with D  val c = new C // prints // val i = i // def j = j 

And it works!

like image 181
Debilski Avatar answered Sep 27 '22 23:09

Debilski