Search code examples
scalaunit-testingconstructorscalatestconstructor-overloading

Scala constructor overloading parameter is not taking effect


I'm trying to understand what's wrong with the way I'm implementing constructor overloading. I want to add a constructor that accepts an argument count, in a class that has a member with the same name.

The idea is to have count calculated off of one of the default constructor parameters, unless it is passed through the overload constructor. I show the code later.

To convince myself this can work, I constructed a quick and simple test:

import org.scalatest.FunSuite

class ConstructorOverloadTest extends FunSuite {

  test("Overload parameter shadows class member") {
    val actual = new TestME(200).length

    200 === actual
    1 !==  actual
  }

  class TestME(name:String) {
    val length = name.length

    def this(length:Int) = {
      this("*")
    }
  }
}

The test passes as expected. Which leads me to understand that the overload constructor parameter length shadows/replaces the class member length.

But when I do the same in another class, the class member is not shadowed/replaced.

class MyClass(input1: Array[Float], input2: Array[Byte], input3: Array[Float]) {

  val count = input2.length

  val index = doSomething()

  def this(count: Int) = {
    this(Array(), Array(), Array())
  }


  def printCount() = {
    if (this.count == 0)
      println("ZERO")
    else
      println("OTHER")
  }
}

When I use this class as follows

val myInstance = new MyClass(200)
myInstance.printCount()

I expect it to print OTHER to the screen. Instead, it prints ZERO.

Why?


Solution

  • There appears to be something wrong with your test. new TestME(200).length returns 1, indicating that the constructor param does not in fact override length.

    class TestME(name:String) {
      val length = name.length
    
      def this(length:Int) = {
        this("*")
      }
    }
    
    println(new TestME(200).length)
    
    1
    

    Per summerbulb's comments:

    1. The test's assertions should be wrapped in assert:

      // Closer to correct...
      assert(200 === actual)
      assert(1 !==  actual)
      
    2. Actual and expected values should be passed in that order:

      // Correct!
      assert(actual === 200)
      assert(actual !== 1)