从父类创建子实例

时间:2020-04-18 19:44:50

标签: scala oop functional-programming aop dsl

我正在为长度操作构建一个简单的DSL。我希望域操作是可扩展的,因此我将它们与域组件的mixins转换一起用作implicit
1.以下是我的应用程序。

package com.shasank.funWithLengths

object LengthAdditionApp extends App{

  val length1 = 11 inches
  val length2 = 15 inches
  val length3 = 2 feet

  println(length1)
  println(length2)
  println(length3)
  println(length1 + length2) // all ok
  println(length1 + length3) // all ok
  println(length3 - length1) // all ok
  println(length1 + length2 + length2) // this breaks since object returned from first operation doesn't have adder

}
  1. 下面是我的基础课。我本来希望它是抽象的,但是由于找不到某种方法来创建子类Inches的实例,因此我将构造方法标记为受保护,以便只有子类才能对其进行扩展,而其他任何事物都不能创建实例。 / li>
package com.shasank.funWithLengths

class Length protected(val measure: Int, val unit: String) {

  private def convertToInches(length: Length)= length.unit match {
    case "feet" => length.measure * 12
    case "inches" => length.measure
  }

  protected def operateOnMeasures(other: Length, op: (Int,Int) => Int): Length ={
    val thisInches = convertToInches(this)
    val otherInches = convertToInches(other)
    val operatedMeasure = op(thisInches,otherInches)
    new Length(operatedMeasure, "inches")  // object created does not have adder & subtracter capabilities
  }

  override def toString = {
    val measureInInches = convertToInches(this)
    val (feetMeasure, inchesMeasure) = BigInt(measureInInches) /% 12
    val feetMeasureString = s"$feetMeasure feet and"
    val inchesMeasureString = s"$inchesMeasure inches"
    s"$feetMeasureString $inchesMeasureString"
  }

}
  1. 以下是我的域组件。
package com.shasank

package object funWithLengths {
  implicit class Inches(measure: Int) extends Length(measure, "inches") with Adder with Subtracter {
    def inches = this
  }
  implicit class Feet(measure: Int) extends Length(measure, "feet") with Adder with Subtracter {
    def feet = this
  }
}
  1. 下面是我的域名运营商。
package com.shasank.funWithLengths

trait Adder extends Length {
  def +(other: Length) = super.operateOnMeasures(other, _+_)
}
package com.shasank.funWithLengths

trait Subtracter extends Length {
  def -(other: Length) = super.operateOnMeasures(other, _-_)
}

问题:有没有办法在我的方法Inches返回的同时创建operateOnMeasures的实例(这样我就可以得到它的所有好处)基类Length

1 个答案:

答案 0 :(得分:0)

我可以通过将Length类移到声明隐式类InchesFeet的包对象中来解决此问题。
这是我工作的链接 code