How to instantiate a class indirectly

If I have several subclasses of a particular abstract class.

abstract class CylindricalProjection(val cut:Double) extends Projection {...}

class PetersProjection(verticalCut:Double= -168.0) extends CylindricalProjection(verticalCut = verticalCut) { ... }

class MercatorProjection(verticalCut:Double= 180.0) extends CylindricalProjection(verticalCut = verticalCut) { ... }

class SimpleProjection(verticalCut:Double= -168.0) extends CylindricalProjection(verticalCut = verticalCut) { ... }

Is there a way for me to instantiate the classes indirectly in a loop, particularly in a test case?
For example, in the file where I define the classes, I’d like to have an object which contains the sequence of classes.

object Foo {
   val projectionClasses = Seq(SimpleProjection, MercatorProjection, PetersProjection)
}

And then in several different test cases do something like the following. Of course this syntax does not work. Just wondering the correct way to do this.

for{ c <- Foo.projectionClasses
      cut <- Seq(-180.0 -120.0, 0.0, 45.0)
      em = EarthMap()(projection = new c(verticalCut= cut))
   } assert( ... something about em ...)

Use the constructors as functions?

val projectionConstructors: Seq[Double => CylindricalProjection] =
  Seq(
    new SimpleProjection(_),
    new MercatorProjection(_),
    new PetersProjection(_)
  )
4 Likes

Like @sangamon said, you should create a Seq of functions. If you change your subclasses into case classes, their generated companion objects will automatically have the function type matching the constructor, so you can write it like in your original post:

val projectionClasses: List[Double => CylindricalProjection] =
  Seq(SimpleProjection, MercatorProjection, PetersProjection)
1 Like

Thanks, that helps. I go back and forth between normal class and case class. Sometimes case class is too much, for example, if I want to create a subclass. sometimes normal class is too little, like the case in point. It’s especially true during program development, when it’s not for certain that the application object model is even correct yet—work in progress.