您可以通过定义一个内部类来覆盖
Enumeration.Val
从而开始操作。为了简化事情,我们称之为
Value
(我们重载了在
Enumeration
中定义的
Value
的原始含义)。
因此,我们有了新的
Value
类型,它继承了
Enumeration.Val
,后者则继承了
Enumeration.Value
。
鉴于
toSql
没有副作用,并且对每个枚举返回不同的字符串,您可能只需将其设置为
val
。
最后,为了使其完全可用,您需要让ConditionOperator.apply和ConditionOperator.withName返回您新定义的
Value
类,而不是在
Enumeration
中定义的
Value
类型。否则,在使用apply或withName按索引/名称查找
ConditionOperator
实例时,您将无法调用toSql,因为枚举类型不够具体。理想情况下,我们希望只覆盖
apply
和
withName
并添加到
ConditionOperator.Value
的转换,但这些方法是final的。
但是,我们可以在这里使用一个小技巧:定义具有相同签名但附加隐式参数的新方法
apply
和
withName
(Predef.DummyImplicit完美地适合此角色)。附加参数确保签名不同,以便我们能够定义这些新方法,同时与原始的apply/withName方法几乎无法区分。Scala的重载解析规则确保编译器选择我们的新方法(因此,在实践中,我们已经遮蔽了原始方法)。
object ConditionOperator extends Enumeration {
class Value(name: String, val toSql: String) extends super.Val(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", "<")
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", "<")
}