Search code examples
scalainner-classes

How to create an inner class instance while using alias name for referring the outer class "this" reference


I have come across a scenario where I am getting compilation error "Cannot Resolve Symbol #INNER_CLASS_NAME" while trying to create an instance of inner class.

Please note that, I am getting this error only when I have created alias name to refer to this reference of enclosing outer class.

Please refer below code snippet for more details :

package netsting

object nested_class4 extends App {

  class Network(val name: String) {
    class Member(val name: String) {
      def description = s"Inner class field name :${Network.this.name}, outer name : ${this.name} "
    }
  }

 
  class Network2(val name: String) { outer => {
      class Member2(val name: String) {
        def description = s"Inner class field name :${outer.name}, outer name : ${this.name} "
      }
   }
  }

  val net1 = new Network("net1")
  val mem1 = new net1.Member("mem1")

  // TODO : How to create instance of inner class while using alias name reference for enclosing class instance
  val net2 = new Network2("net1")
  val mem2 = new net2.Member2("mem1")
  println(mem2.description)
}

Here, In above example, I am able to create instance of inner class Network#Member without any error. But, I am getting compilation error while trying to create instance of inner class Network2#Member2.

enter image description here

Here, the compilation error goes away if I remove the alias name "outer" and just use the casual way Network.this.name to refer to enclosing class fields.

What is the correct way to create instance of inner class when we have created alias name to refer to this reference of outer class ?


Solution

  • The syntax for an "alias name" does not include any extra braces:

    class Network2(val name: String) { outer => // MUST be like this
      class Member2(val name: String) {
        def description = s"Inner class field name: ${outer.name}, outer name: ${this.name}"
      }
    }
    // WRONG
    class Network2Bad(val name: String) { outer => { ??? } }
    // same as
    // class Network2Bad(val name: String) { { ??? } }
    // the body of this class consists of a block expression { ??? }
    // which is evaluated whenever a Network2Bad is constructed
    // by ordinary scoping rules, nothing declared in that block is declared in the enclosing scope (the Network2Bad object)
    val net2 = new Network2("net2")
    val mem2 = new net2.Member2("mem2")
    println(mem2.description)
    

    P.S. the only official name I know of for what you can an "alias name" is "self type".