scala/ScalaBook/chapter-12/src/main/scala/scalabook/ep/dc/sub/sub.scala
package scalabook.ep.dc.sub
/**
* Definitions for a Data-Centric approach with subclassing.
*
* @author Christos KK Loverdos
*/
// We add a new operation: string representation of data
// By extending tha base data trait.
// This means we must add the new operation to all concrete
// data implementations
trait ReprD extends BaseD {
def repr: String
}
// Extension (via subclassing) of literal numbers that supports
// string representation
class ReprNumD(value: Int) extends NumD(value) with ReprD {
def repr = value.toString
}
// Extension (via subclassing) of added data that supports
// string representation
class ReprPlusD(a: ReprD, b: ReprD) extends PlusD(a, b) with ReprD {
def repr = a.repr + " + " + b.repr
}
object AutoRepr {
// But in {@link ReprNumD} the type of the constructor arguments
// are ReprD and not BaseD, so we cannot reuse pre-existing BaseD
// instances...
// One way out of this is to create a few implicit conversions...
implicit def NumD2ReprNumD(data: NumD) = new ReprNumD(data.eval)
}
// Another line of attack, apart from the above implicit, is to provide
// auxiliary constructors...
class ReprNumD2(value: Int) extends NumD(value) with ReprD {
def this(numd: NumD) = this(numd.eval)
def repr = value.toString
}
// Yet another slight modification in the above alternative to ReprNumD,
// is to have the auxiliary constructor take any BaseD as a parameter
// and not just NumD
class ReprNumD3(value: Int) extends NumD(value) with ReprD {
def this(data: BaseD) = this(data.eval)
def repr = value.toString
}