我想象每个人都继续前进,现在这个问题已经存在一年半了,但我仍然很惊讶没有人提供 Groovy 类别作为解决方案。事实上,在我看来,类别是解决这个问题的最自然的方法。在不更改原始域类的“Grailsiness”的情况下,您仍然可以相对容易地灌输所需的数字行为。
首先定义类别类:
class ScoreCategory {
static asType(Score s, Class newClass) {
switch (newClass) {
case Integer.class:
case Integer.TYPE:
case Number.class: return s?.value ?: 0
default: throw new GroovyCastException("Cannot cast to ${newClass}")
}
}
static boolean equals(Score me, def you) {
you instanceof Score && me as int == you as int
}
static Score plus(Score a, b) { plusImpl(a, b) }
static Score plus(Score a, Number b) { plusImpl(a, b) }
static Score plus(Number a, Score b) { plusImpl(a, b) }
private static plusImpl(a, b) { new Score(value: (a as int) + (b as int)) }
static Score minus(Score a, b) { minusImpl(a, b) }
static Score minus(Score a, Number b) { minusImpl(a, b) }
static Score minus(Number a, Score b) { minusImpl(a, b) }
private static minusImpl(a, b) { a + -b }
static Score multiply(Score a, Number b) { multImpl(a,b) }
static Score multiply(Number a, Score b) { multImpl(a,b) }
private static multImpl(a,b) { new Score(value: (a as int) * (b as int)) }
static Integer div(Score a, b) { (a as int).intdiv(b as int) }
static Score div(Score a, Number b) { new Score(value:(a as int).intdiv(b as int)) }
static Score negative(Score a) { new Score(value: -(a as int)) }
static Score abs(Score a) { new Score(value: (a as int).abs())}
}
然后,在应用程序中某个适当的全局位置声明 mixins:
Number.metaClass.mixin ScoreCategory
Score.metaClass.mixin ScoreCategory
毕竟,如下所示,Score
对象现在应该表现得像数字量:
def (w, x, y, z) = [54, 78, 21, 32]
def (s1, s2) = [new Score(value:w), new Score(value:x)]
assert (s1 + s2) == new Score(value: w + x)
assert (s1 + y) == new Score(value: w + y)
assert (z + s2) == new Score(value: z + x)
assert (s1 - s2) == new Score(value: w - x)
assert (s1 - y) == new Score(value: w - y)
assert (z - s2) == new Score(value: z - x)
assert (s1 * y) == new Score(value: w * y)
assert (z * s2) == new Score(value: z * x)
assert (s2 / s1) == x.intdiv(w)
assert (s1 / y) == new Score(value: w / y)