score:17

Accepted answer

Let's call the class class SomeClass (though it could also be e.g. a trait).

Private members

Methods of the companion object (object SomeClass) have access to private methods/data of instances of class SomeClass.

If your companion object only uses the public interface of your class (e.g. just defines constants), there's no practical difference. But there are a number of cases where it's useful to let utility functions access private members. For example, object SomeClass could define a factory method apply that sets up private members of class SomeClass, without having to expose setters in the public interface. In such cases, you must therefore define a companion object by putting the definition of object SomeClass in the same compilation unit as class SomeClass.

Another difference is that the compiler searches for implicits in companion objects of a type (and its supertypes). So if you are using implicit conversions you define in the code of class SomeClass, you must define them in the companion object.

Comments

The combination of the two also explains the same-compilation-unit restriction.

  • scalac can't compile object SomeClass until it knows what private members of class SomeClass it calls.
  • scalac can't compile class SomeClass until it knows what implicits it calls. So the companion object must be compiled no later than class SomeClass.

It follows they must be compiled at the same time. Further, the current compiler apparently compiles separate files separately (cf. the lack of support for splitting classes across multiple files), restricting it to the same compilation unit.


Related Query