具有伴生对象的类与同名的类和对象有什么区别?

2024-04-04

Scala 类的“伴生对象”可以被视为具有与该类相同的完全限定名称的单例对象(即相同的名称,在同一包中)。它们用于保存类的所有实例共有的实用函数,作为 Java 的替代品static方法。

然而,在文档和问题的不同地方,它说伴生对象必须在同一编译单元中定义。例如,它们必须定义在同一个文件中;不能为 Java 对象定义伴生对象 https://stackoverflow.com/questions/4921827/in-scala-how-can-i-define-a-companion-object-for-a-class-defined-in-java; 在 REPL 中,它们必须在同一输入行上定义 https://stackoverflow.com/questions/6919965/companion-object-cannot-access-private-variable-on-the-class,因此出现警告消息:

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.

这意味着类及其伴生对象之间必须存在区别,而类和对象之间必须具有相同(完全限定)名称。这个区别是什么?


我们来称呼班级吧class SomeClass(尽管它也可能是例如trait).

私人会员

伴随对象的方法(object SomeClass) 可以访问私有方法/数据的实例数class SomeClass.

如果您的伴生对象仅使用类的公共接口(例如,仅定义常量),则没有实际差异。但在许多情况下,让实用程序函数访问私有成员是很有用的。例如,object SomeClass可以定义一个工厂方法apply设置私人成员class SomeClass,而不必在公共接口中公开设置器。因此,在这种情况下,您必须通过将以下定义定义为伴生对象:object SomeClass在同一个编译单元中class SomeClass.

另一个区别是编译器在类型(及其超类型)的伴生对象中搜索隐式 http://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html#companion_objects_of_a_type。因此,如果您使用隐式转换,则在代码中定义class SomeClass,您必须在伴生对象中定义它们。

Comments

两者的结合也解释了相同编译单元的限制。

  • scalac无法编译object SomeClass直到它知道私有成员是什么class SomeClass它呼唤。
  • scalac无法编译class SomeClass直到它知道它调用的隐式是什么。因此,伴生对象必须在不晚于class SomeClass.

因此它们必须同时编译。此外,当前的编译器显然是单独编译单独的文件(参见缺乏对跨多个文件拆分类的支持),将其限制为同一编译单元。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有伴生对象的类与同名的类和对象有什么区别? 的相关文章

随机推荐