您可以从定义一个覆盖Enumeration.Val
. 为简化起见,我们称它为(我们重载了定义Value
的原意)。所以我们有了新的类型,它继承了它本身继承了。Value
Enumeration
Value
Enumeration.Val
Enumeration.Value
鉴于它toSql
没有副作用并为每个枚举返回不同的字符串,您不妨将其设为val
.
最后,为了使其完全可用,您需要让 ConditionOperator.apply 和 ConditionOperator.withName 返回新定义的Value
类,而不是. 否则,当使用 apply 或 withName 按索引/名称查找实例时,将无法调用 toSql,因为枚举类型不够具体。理想情况下,我们只想覆盖并添加强制转换,但这些方法是最终的。但是我们可以在这里使用一个小技巧:定义新方法 和Value
Enumeration
ConditionOperator
apply
withName
ConditionOperator.Value
apply
withName
具有相同的签名,但有一个始终可用的附加隐式参数(Predef.DummyImplicit 非常适合此卷)。附加参数确保签名不同,以便我们能够定义这些新方法,同时与原始的 apply/withName 方法几乎没有区别。scala 中重载解析的规则确保我们的新方法是编译器喜欢的方法(因此我们在实践中隐藏了原始方法)。
object ConditionOperator extends Enumeration {
// Here we overload the meaning of "Value" to suit our needs
class Value(name: String, val toSql: String) extends super.Val(name) {
def someFlag: Boolean = true // An example of another method, that you can override below
}
val Equal = new Value("equal", "=")
val NotEqual = new Value("notEqual", "<>")
val GreaterOrEqual = new Value("greaterOrEqual", ">=")
val Greater = new Value("greater", ">")
val LessOrEqual = new Value("lessOrEqual", "<=") { override def someFlag = false }
val Less = new Value("less", "<")
final def apply(x: Int)( implicit dummy: DummyImplicit ): Value = super.apply(x).asInstanceOf[Value]
final def withName(s: String)( implicit dummy: DummyImplicit ): Value = super.withName(s).asInstanceOf[Value]
}
您可以检查您现在是否可以执行ConditionOperator(2).toSql
ConditionOperator.withName("greaterOrEqual") 之类的操作,它们都按预期返回 ">="。最后,上面的体操可以抽象掉:
abstract class CustomEnumeration extends Enumeration {
type BaseValue = super.Val
type CustomValue <: super.Value
type Value = CustomValue
final def apply(x: Int)( implicit dummy: DummyImplicit ): CustomValue = super.apply(x).asInstanceOf[CustomValue]
final def withName(s: String)( implicit dummy: DummyImplicit ): CustomValue = super.withName(s).asInstanceOf[CustomValue]
}
object ConditionOperator extends CustomEnumeration {
class CustomValue(name: String, val toSql: String) extends BaseValue(name) {
def someFlag: Boolean = true
}
val Equal = new Value("equal", "=")
val NotEqual = new Value("notEqual", "<>")
val GreaterOrEqual = new Value("greaterOrEqual", ">=")
val Greater = new Value("greater", ">")
val LessOrEqual = new Value("lessOrEqual", "<=") { override def someFlag = false }
val Less = new Value("less", "<")
}