什么是与同伴对象和类和对象具有相同名称的类之间的区别?(What's the differe

2019-07-30 12:58发布

Scala的类的“伴侣对象”可以被看作是具有相同的完全合格的名称作为类一个单独的对象(即,相同的名称,在同一个包中)。 它们被用来保持共同的类的所有实例的实用功能,作为Java的替代static方法。

然而,在文档和问题不同的地方,它说,同伴对象必须在同一个编译单元定义。 例如,它们必须在相同的文件中定义; 同伴对象不能为Java对象定义 ; 在REPL,它们必须在相同的输入线来限定 ,因此警告消息:

warning: previously defined class Foo is not a companion to object Foo.
Companions must be defined together; you may wish to use :paste mode for this.

这意味着,必须有与它的同伴对象的类,只是一个类和对象以相同的(完全限定)名称之间的区别。 这是什么区别?

Answer 1:

让我们调用类class SomeClass (尽管它也可以如trait )。

私有成员

同伴对象(方法object SomeClass访问的情况下, 私有方法/数据 class SomeClass

如果你的伴侣的对象只使用你的类的公有接口(例如仅仅定义常量),没有实际的区别。 但也有许多情况下,它是有用的,让实用功能访问私有成员。 例如, object SomeClass可以定义一个工厂方法apply ,设置了的私有成员class SomeClass ,而不必在公共接口暴露setter方法。 在这种情况下,你必须因此通过把定义定义一个同伴对象object SomeClass在同一编译单元的class SomeClass

另一个区别在于, 编译器用于在类型(及其超类型)的伴侣对象implicits搜索 。 所以,如果你使用你的代码中定义的隐式转换class SomeClass ,你必须在同伴对象定义它们。

评论

两者的结合,也说明了同样的编译单元的限制。

  • scalac不能编译object SomeClass ,直到它知道什么的私有成员class SomeClass调用。
  • scalac不能编译class SomeClass ,直到它知道什么implicits它调用。 所以同伴对象必须不迟于编译class SomeClass

它遵循他们必须在同一时间进行编译。 此外,电流的编译器显然单独编译独立的文件(参见缺乏对在多个文件分割类的支持),将其限制到相同的编译单元。



文章来源: What's the difference between a class with a companion object and a class and object with the same name?