为什么以及什么时候特征和对象应该具有相同的名称?

Why and when should trait and object have same name?

是什么原因
  trait Dog {
    def bark = "woof"
  }
  object Dog extends Dog

有效,但以下无效

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

我在某处读到,在上面提到的第一种情况下,对象不是伴随对象。 object 和 trait 同名是什么场景?

从介绍到第 2 章 (Identifiers, Names & Scopes):

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

第 5.5 节 (Object definitions) 几乎完全包含您的示例(使用 Point 而不是 Dog),并带有以下注释:

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.

(强调我的)

您使用 class Dog extends Dog 的第二个示例不起作用,因为 class Dogtrait Dog 最终都出现在类型的命名空间中,这会导致冲突。

Companion objects 用于任何你想使用静态方法的地方,例如Java(除了伴随对象更好,因为它们是 对象,并且可以作为普通值传递)。

这种情况 object Foo extends Foo 看起来有些做作而且很不常见。你有一个使用它的实际例子吗?如果不是,那么它只是一个形式上有效的极端情况,只是因为它没有被明确禁止。

编辑object AnsiColor extends AnsiColor 似乎是 object X extends X 模式最 "important" 的应用之一。

第二个示例在这里失败的原因是 不是 因为 Dog 不是伴随对象,而是因为您定义了一个新的副本 class Dog。我总是将 traitsclasses 视为一个类别,将 objects 视为另一个类别 - object 是特征或 class.[=18 的单例实例=]

为什么不能创建同名的 classes? 如果允许的话,是不可能区分两个实体的。

为什么您可以 创建 (class/trait) 和具有相同名称的对象? 您可以区分它们,因为 classtraittype 而 object 是 value.

什么时候应该将对象命名为与 classes 相同的名称? 如果您不想定义伴随对象,那么您对该对象的隐含将起作用。或者,如果您想在对象上定义方便的 apply 方法。否则我根本不会为对象是 companion 或不是 companion 而烦恼,但为了方便起见,我经常创建名称为 class 的对象。