Search code examples
scalaoopabstract-classcase-class

How can I extend an abstract class with an optional member in Scala?


I have an abstract base class, Foo, whose constructor I'd like to have an optional parameter. If none is provided, I'll just give it a None value.

A source Foo will not have parents, so I'd just like to construct them without a list of parents (leave default value for parent list)

A derived Foo might have provided parents, so I'd like to mimic the signature of the Foo base class.

Below is my attempt:

abstract class Foo(val id: String, var parentIds: Option[List[String]]=None) { }

case class SourceFoo(override val id: String)
  extends Foo(id, parentIds=None) { }

case class DerivedFoo(override val id: String, 
                      override var parentIds: Option[List[String]])
  extends Foo(id, parentIds) { }

I'm getting a compiler error that a mutable variable cannot be overridden (referencing the parentIds in the DerivedFoo constructor.

This list is subject to change, so I don't want to make it a val (which removes my compiler issues).

This is a very basic OO issue, so it must be simpler than I seem to be making it. How can I achieve my desired behavior idiomatically?


Solution

  • I managed to fix this after reading the documentation:

    The constructor parameters of case classes are treated as public values and can be accessed directly.

    Since my base class is abstract, I can simply extend it with default, val construction.

    I simply need to specify that parentIds is a var in the DerivedFoo constructor.

    abstract class Foo(id: String, parentIds: Option[List[String]]=None) { }
    
    case class SourceFoo(id: String) extends Foo(id) { }
    
    case class DerivedFoo(id: String, var parentIds: Option[List[String]]=None) 
        extends Foo(id, parentIds) { }