Search code examples
scalatraitscompanion-object

Why and when should trait and object have same name?


What is the reason that

  trait Dog {
    def bark = "woof"
  }
  object Dog extends Dog

works, but the following does not

trait Dog {
  def bark = "woof"
}
class Dog extends Dog

I read somewhere that in the first case mentioned above the object is not a companion object. What is the scenario when object and trait should have the same name ?


Solution

  • From introduction to Chapter 2 (Identifiers, Names & Scopes):

    There are two different name spaces, one for types and one for terms.

    Section 5.5 (Object definitions) contains almost exactly your example (with Point instead of Dog), with the following comment:

    Note that the double use of the name Point is legal, since the class definition defines the name Point in the type name space, whereas the object definition defines a name in the term namespace.

    (emphasis mine)

    Your second example with class Dog extends Dog does not work, because both the class Dog and trait Dog end up in the namespace for types, and this results in a conflict.

    Companion objects are used whenever you would use static methods in e.g. Java (except that companion objects are much nicer, because they are, well, objects, and can be passed around as ordinary values).

    The situation object Foo extends Foo appears somewhat contrived and rather uncommon. Have you an actual example where it is used? If not, then it's just a corner case that is formally valid, simply because it's not explicitly prohibited.

    EDIT: object AnsiColor extends AnsiColor seems to be one of the most "important" applications of the object X extends X pattern.