Search code examples
scalaabstract-classadditionoperation

Implement addition in abstract Scala class


I have the below abstract class and its two subclasses:

abstract class BoundedNumber(val lowerBound: Double,
                             val upperBound: Double,
                             val value: Double) {
  require(value >= lowerBound && value <= upperBound)
}

final case class Percentage(override val value: Double)
  extends BoundedNumber(0, 100, value)

final case class Probability(override val value: Double)
  extends BoundedNumber(0, 1, value)

Can I somehow implement a "generic" addition in BoundedNumber even though it's abstract and cannot be instantiated?

abstract class BoundedNumber(val lowerBound: Double,
                             val upperBound: Double,
                             val value: Double) {
  def +(that: BoundedNumber): BoundedNumber = {
    require(this.getClass == that.getClass)
    // This of course won't compile:
    new BoundedNumber(lowerBound, upperBound, value + that.value)
  }
}

Or am I bound to (pun intended) implement addition in both subclasses thus duplicating code?


Solution

  • You cannot instantiate abstract class, However you can specify an abstract method in BoundedNumber that create new instance with required updated value.

      abstract class BoundedNumber(val lowerBound: Double,
                                   val upperBound: Double,
                                   val value: Double) {
        require(value >= lowerBound && value <= upperBound)
    
        def copy(value: Double): BoundedNumber
    
        def +(that: BoundedNumber): BoundedNumber = {
          require(this.getClass == that.getClass)
          that.copy(value + that.value)
        }
      }
    
      final case class Percentage(override val value: Double) extends BoundedNumber(0, 100, value) {
        override def copy(value: Double): BoundedNumber =  Percentage(value)
      }
    
      final case class Probability(override val value: Double) extends BoundedNumber(0, 1, value){
        override def copy(value: Double): BoundedNumber = Probability(value)
      }