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

后端 未结 2 615
星月不相逢
星月不相逢 2021-01-01 12:09

I have

trait Invoker {
  val method: Method
}

Intellij IDEA code inspection is warning me that \"Abstract value used in trait\". Everythin

2条回答
  •  天涯浪人
    2021-01-01 12:48

    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!

提交回复
热议问题