正确使用Scala特征和案例对象

kee*_*gan 3 scala

试图了解Scala类和特征,这是一个简单的例子.我想定义一个指定各种操作的类,可以通过多种方式实现.我可能会开始,

sealed trait Operations{
  def add
  def multiply
}
Run Code Online (Sandbox Code Playgroud)

因此,例如,我可以使用一个对象来实例化这个类add,multiply非常明智,

case object CorrectOperations extends Operations{
    def add(a:Double,b:Double)= a+b
    def multiply(a:Double,b:Double)= a*b
}
Run Code Online (Sandbox Code Playgroud)

而且,可能还有其他方法来定义这些操作,例如这显然是错误的方式,

case object SillyOperations extends Operations{
    def add(a:Double,b:Double)= a + b - 10
    def multiply(a:Double,b:Double)= a/b
}
Run Code Online (Sandbox Code Playgroud)

我想将这样的实例传递给一个以特定方式执行操作的函数.

 def doOperations(a:Double,b:Double, op:operations) = {
   op.multiply(a,b) - op.add(a,b)
 }
Run Code Online (Sandbox Code Playgroud)

我想doOperations采取任何类型的对象,operations以便我可以利用addmultiply,无论它们是什么.

我需要改变什么doOperations,以及我在这里误解了什么?谢谢

Dan*_*yes 5

没有运行你的代码,但我想你有一个编译错误.

如果您没有在特征中定义方法的签名Operations,那么默认情况下它将被解释为() => Unit.

这意味着继承对象中的方法并没有真正覆盖特征中的方法,而是定义了重载.在这里查看更多相关信息.您可以通过override在对象方法中编写方法定义来验证这一点.这将迫使编译器明确警告您,这些方法不会覆盖祖先特征中的任何内容,并且可以作为抵御类似错误的"安全网".

要修复错误,请拼写出特征的签名,如下所示:

sealed trait Operations{
  def add(a:Double,b:Double):Double
  def multiply(a:Double,b:Double):Double
}
Run Code Online (Sandbox Code Playgroud)

实际上,在继承对象的方法中甚至不需要输出参数类型(但请注意添加的override属性):

case object CorrectOperations extends Operations{
    override def add(a:Double,b:Double) = a+b
    override def multiply(a:Double,b:Double) = a*b
}
Run Code Online (Sandbox Code Playgroud)