正确使用 Scala 特征和案例对象 [英] Proper use of Scala traits and case objects
问题描述
试图掌握 Scala 类和特征的窍门,这里有一个简单的例子.我想定义一个指定各种操作的类,可以通过多种方式实现.我可能会开始,
Trying to get the hang of Scala classes and traits, here's a simple example. I want to define a class which specifies a variety of operations, that could be implemented in lots of ways. I might start with,
sealed trait Operations{
def add
def multiply
}
例如,我可能会用一个对象实例化这个类,add
和 multiply
非常明智,
So for example, I might instantiate this class with an object does that add
and multiply
very sensibly,
case object CorrectOperations extends Operations{
def add(a:Double,b:Double)= a+b
def multiply(a:Double,b:Double)= a*b
}
而且,可能还有其他方式来定义这些操作,例如这种明显错误的方式,
And also, there could be other ways of defining those operations, such as this obviously wrong way,
case object SillyOperations extends Operations{
def add(a:Double,b:Double)= a + b - 10
def multiply(a:Double,b:Double)= a/b
}
我想将这样的实例传递给一个函数,该函数将以特定方式执行操作.
I would like to pass such an instance into a function that will execute the operations in a particular way.
def doOperations(a:Double,b:Double, op:operations) = {
op.multiply(a,b) - op.add(a,b)
}
我希望 doOperations
接受 operations
类型的任何对象,以便我可以使用 add
和 multiply
,不管它们是什么.
I would like doOperations
to take any object of type operations
so that I can make use of the add
and multiply
, whatever they may be.
关于doOperations
,我需要改变什么,我在这里有什么误解?谢谢
What do I need to change about doOperations
, and what am I misunderstanding here? Thanks
推荐答案
尚未运行您的代码,但我想您遇到了编译错误.
Haven't ran your code, but I suppose you got a compilation error.
如果你没有在 Operations
trait 中定义方法的签名,那么默认情况下它会被解释为 () =>单位
.
If you don't define the signature of the methods in the Operations
trait, then by default it will be interpreted as () => Unit
.
这意味着继承对象中的方法并没有真正覆盖特征中的方法,而是定义了重载.在此处查看更多相关信息.您可以通过在对象方法中的方法定义前写入 override
来验证这一点.这将迫使编译器明确警告您这些方法不会覆盖祖先特征中的任何内容,并且可以作为防止类似错误的安全网".
This means that the methods in the inheriting objects are not really overriding the methods in the trait, but define overloads instead. See more about that here. You can verify this by writing override
in front of the method definitions in the object methods. That will force the compiler to explicitly warn you that the methods are not overriding anything from the ancestor trait, and works as a "safety net" against similar mistakes.
要修复该错误,请按如下方式拼出特征的签名:
To fix the bug, spell out the signature of the trait like the following:
sealed trait Operations{
def add(a:Double,b:Double):Double
def multiply(a:Double,b:Double):Double
}
实际上,在继承对象的方法中甚至不需要输出参数类型(但要注意添加的override
属性):
In fact, the output parameter types are not even necessary in the methods of the inheriting objects (but note the added override
attributes):
case object CorrectOperations extends Operations{
override def add(a:Double,b:Double) = a+b
override def multiply(a:Double,b:Double) = a*b
}
这篇关于正确使用 Scala 特征和案例对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!