什么原因
trait Dog {
def bark = "woof"
}
object Dog extends Dog
有效,但以下无效
trait Dog {
def bark = "woof"
}
class Dog extends Dog
我在某处读到,在上述第一种情况下,该对象不是伴随对象。对象和特征应该具有相同的名称时会发生什么情况?
答案 0 :(得分:5)
从简介到第2章(Identifiers, Names & Scopes):
有两种不同的名称空间,一种用于类型,一种用于术语。
第5.5节(Object definitions)几乎完全包含您的示例(使用Point
而不是Dog
),并带有以下注释:
请注意,重复使用名称
Point
是合法的,因为类定义在 type 命名空间中定义名称Point,而对象定义在< strong> term 名称空间。
(重点是我的)
您使用class Dog extends Dog
的第二个示例不起作用,因为class Dog
和trait Dog
都位于类型的名称空间中,这会导致冲突。
随同object
会在您要在其中使用静态方法时使用。 Java(除了伴随对象更好,因为它们是 object ,并且可以作为普通值传递)。
object Foo extends Foo
的情况似乎有些人为的,而且很不常见。您有使用它的实际示例吗?如果不是,那么这只是形式上有效的一个极端案例,仅仅是因为没有明确禁止。
编辑:object AnsiColor extends AnsiColor
似乎是object X extends X
模式中最“重要”的应用程序之一。
答案 1 :(得分:3)
第二个示例在此处失败的原因是 not ,因为Dog不是伴随对象,而是因为您定义了一个新的重复类Dog。我总是将traits
和classes
视为一个类别,将objects
视为另一类别-object
是特征或类别的单例实例。
为什么不能创建具有相同名称的类? 如果允许的话,不可能区分两个实体。
为什么您可以创建具有相同名称的(类/特征)和对象?
您可以区分它们,因为class
或trait
是 type ,而object是 value 。
何时应为对象命名与类相同的名称?
如果您不想定义伴随对象,那么您对该对象的隐式将起作用。或者,如果您想在对象上定义方便的apply
方法。否则,我根本不会为自己的任何一个对象是companion
而烦恼自己,但是为了方便起见,经常使用类名创建对象。