所以我是Scala的新手(几乎没有java经验(。我认为我抽象地理解OOP,但忽略了这一点。我的问题——类似于"使用伴随对象时的方法名称限定"——是关于Scala专业人员何时会考虑实现类伴随对象模式?
从上面提到的问题来看,不清楚伴随对象是否用于存储类的"内部使用"方法(例如,发布者想要使用^,在对象中定义,在类中定义(。所以,我不想把伴随对象看作伴随类可以使用的方法的"容器",因为这显然不是真的。。。
如果这是一个模糊的问题,我很抱歉:我只想知道使用这些家伙的正确方法。
Companion对象对于在Java中使用静态方法非常有用。。。
一个非常常见的用途是在伴随对象中定义一个apply()
方法,这让用户能够使用MyObject(arg, arg)
作为new MyObject(arg, arg)
的简写。
配套对象也是放置隐式def之类的东西的好地方。
我最近一直在我的akka应用程序中使用配套对象作为放置消息用例类的地方,这些类是特定于主管参与者及其子系统的,但我不一定希望该子系统之外的代码直接使用。
这里有一个简单的例子:
class Complex(real:Double, imag:Double) {
def +(that:Complex):Complex = Complex(this.real + that.real, this.imag + that.imag)
// other useful methods
}
// the companion object
object Complex {
def apply(real:Double, imag:Double) = new Complex(real, imag)
val i = Complex(0, 1)
implicit def fromInt(i:Int) = Complex(i, 0)
}
实例化一个新的复杂对象的普通OOP方法是new Complex(x, i)
。在我的配套对象中,我定义了函数apply
,为我们提供了一个语法糖,使我们能够编写Complex(x, i)
。apply
是一个特殊的函数名,每当您直接调用对象时,它就会被调用,就像它是一个函数一样(即Complex()
(。
我还有一个名为i
的值,其计算结果为Complex(0, 1)
,这为我提供了使用公共复数i
的简写。
这可以在Java中使用静态方法来实现,例如:
public static Complex i() {
return new Complex(0, 1);
}
伴随对象本质上为您提供了一个附加到类名的命名空间,该命名空间并不特定于类的特定实例。