特性和对象为何以及何时应具有相同的名称?

时间:2019-01-14 18:00:14

标签: scala traits companion-object

什么原因

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

有效,但以下无效

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

我在某处读到,在上述第一种情况下,该对象不是伴随对象。对象和特征应该具有相同的名称时会发生什么情况?

2 个答案:

答案 0 :(得分:5)

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

  

有两种不同的名称空间,一种用于类型,一种用于术语

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

  

请注意,重复使用名称Point是合法的,因为类定义在 type 命名空间中定义名称Point,而对象定义在< strong> term 名称空间。

(重点是我的)

您使用class Dog extends Dog的第二个示例不起作用,因为class Dogtrait Dog都位于类型的名称空间中,这会导致冲突。

随同object会在您要在其中使用静态方法时使用。 Java(除了伴随对象更好,因为它们是 object ,并且可以作为普通值传递)。

object Foo extends Foo的情况似乎有些人为的,而且很不常见。您有使用它的实际示例吗?如果不是,那么这只是形式上有效的一个极端案例,仅仅是因为没有明确禁止。

编辑object AnsiColor extends AnsiColor似乎是object X extends X模式中最“重要”的应用程序之一。

答案 1 :(得分:3)

第二个示例在此处失败的原因是 not ,因为Dog不是伴随对象,而是因为您定义了一个新的重复类Dog。我总是将traitsclasses视为一个类别,将objects视为另一类别-object是特征或类别的单例实例。

为什么不能创建具有相同名称的类? 如果允许的话,不可能区分两个实体。

为什么您可以创建具有相同名称的(类/特征)和对象? 您可以区分它们,因为classtrait type ,而object是 value

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