在抽象Scala类中实现加法

时间:2018-07-03 05:22:59

标签: scala abstract-class addition operation

我有下面的抽象类及其两个子类:

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)

我能以某种方式在BoundedNumber中实现“通用”加法,即使它是抽象的且无法实例化吗?

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)
  }
}

还是我必须(在双关语中)在两个子类中实现加法,从而复制代码?

3 个答案:

答案 0 :(得分:3)

您无法实例化抽象类,但是可以在Sub Duplicates() Dim i As Long i = ActiveSheet.UsedRange.Rows.Count x = Cells(2, 2).Value For j = 3 To i If Cells(j, 2).Value = "" Then Cells(j, 2).Value = x Else x = Cells(j, 2).Value End If Next j End Sub 中指定一个抽象方法,该方法使用所需的更新值来创建新实例。

BoundedNumber

答案 1 :(得分:1)

如果您的目标是编译时类型安全,而+的两个操作数必须是相同的具体类型,并且+也返回相同的具体类型,则可以声明一个抽象类型和构造函数,将由每个具体的子类实现。然后可以在抽象类中定义+

abstract class BoundedNumber(val lowerBound: Double, val upperBound: Double, val value: Double) {
    require(value >= lowerBound && value <= upperBound)
    type Self <: BoundedNumber
    def make(value: Double): Self

    def +(that: Self): Self = make(value + that.value)
}

final case class Percentage(override val value: Double) extends BoundedNumber(0, 100, value) {
    type Self = Percentage
    def make(value: Double): Self = Percentage(value)
}

final case class Probability(override val value: Double) extends BoundedNumber(0, 1, value) {
    type Self = Probability
    def make(value: Double): Self = Probability(value)
}

现在,编译器将正确推断+Percentage的参数必须为Percentage类型,并且结果将为Percentage类型。

答案 2 :(得分:-1)

在抽象类中创建一个具体的类并返回:

abstract class BoundedNumber(val lowerBound: Double,
                             val upperBound: Double,
                             val value: Double) {

  class ConcreteBoundedNumber(lowerBound: Double,
                              upperBound: Double,
                              value: Double) extends BoundedNumber(lowerBound, upperBound, value)

  def +(that: BoundedNumber): BoundedNumber = {
    require(this.getClass == that.getClass)

    new ConcreteBoundedNumber(lowerBound, upperBound, value + that.value)
  }
}

这提供了+的通用实现,而没有在子类中添加任何代码。