在抽象 Scala 中实现加法 class
Implement addition in abstract Scala class
我有以下摘要 class 及其两个子class:
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
中实现 "generic" 添加,即使它是抽象的且无法实例化?
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)
}
}
或者我是否必须(双关语)在两个子classes 中实现加法从而重复代码?
您不能实例化抽象 class,但是您可以在 BoundedNumber
中指定一个抽象方法,用所需的更新值创建新实例。
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)
}
在抽象 class 和 return 中创建一个具体的 class :
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)
}
}
这给出了 +
的通用实现,无需向子 class 中添加任何代码。
如果您的目标是编译时类型安全,即 +
的两个操作数必须具有相同的具体类型并且 +
也 returns 具有相同的具体类型,您可以声明一个抽象类型和构造函数,它将由每个具体的 subclass 实现。 +
然后可以在摘要中定义 class:
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
类型。
我有以下摘要 class 及其两个子class:
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
中实现 "generic" 添加,即使它是抽象的且无法实例化?
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)
}
}
或者我是否必须(双关语)在两个子classes 中实现加法从而重复代码?
您不能实例化抽象 class,但是您可以在 BoundedNumber
中指定一个抽象方法,用所需的更新值创建新实例。
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)
}
在抽象 class 和 return 中创建一个具体的 class :
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)
}
}
这给出了 +
的通用实现,无需向子 class 中添加任何代码。
如果您的目标是编译时类型安全,即 +
的两个操作数必须具有相同的具体类型并且 +
也 returns 具有相同的具体类型,您可以声明一个抽象类型和构造函数,它将由每个具体的 subclass 实现。 +
然后可以在摘要中定义 class:
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
类型。