scala/ScalaBook/chapter-12/src/main/scala/scalabook/ep/oc/sub/sub.scala
package scalabook.ep.oc.sub
/**
* Definitions for an Operation-Centric approach with subclassing.
* @author Christos KK Loverdos
*/
// The difficult part in the op-centric approach is of course how
// to define new data.
// Here we define data combined with a plus...
// ...............BUT.....................
// the obvious definition:
///////////////////////////////////////////////////
// def perform(op: PlusOp) {
// op.computePlusD(this)
// }
///////////////////////////////////////////////////
// will not compile with the following error:
///////////////////////////////////////////////////
// class PlusD needs to be abstract, since method perform in trait BaseD of type (scalabook.ep.oc.BaseOp)Unit is not defined
// class PlusD(val a: BaseD, val b: BaseD) extends BaseD {
// ^
///////////////////////////////////////////////////
// so we resort to a change in the argument type and a type-cast
class PlusD(val a: BaseD, val b: BaseD) extends BaseD {
/* This will not compile, as explained above
override def perform(op: PlusOp) {
op.computePlusD(this)
}*/
// necessary change in order to compile...
def perform(op: BaseOp) {
op.asInstanceOf[PlusOp].computePlusD(this)
}
}
// ... and then we subclass the base operation to support
// this new kind of data
trait PlusOp extends BaseOp {
def computePlusD(data: PlusD)
}
// ... and implement our 1s concrete extension: evaluation
// of the extended data....
trait PlusEvalOp extends EvalOp {
def computePlusD(data: PlusD) {
this.result = Some(eval(data.a) + eval(data.b))
}
}