协慌网

登录 贡献 社区

Scala 中对象和类之间的区别

我刚刚浏览了 Internet 上的一些 Scala 教程,并注意到在某些示例中,在示例开始时声明了一个对象。

Scala 中的classobject什么区别?

答案

tl; dr

  • 与 Java 或 C ++ 一样, class C
  • object O创建一个单例对象O作为某个匿名类的实例;它可以用来保存与某个类的实例不相关的静态成员。
  • object O extends T使对象O trait T的实例; 然后,您可以将O传递到任何一个T位置。
  • 如果有class C ,那么object CC的伴随对象; 请注意,伴随对象并非自动为C的实例。

另请参见 Scala 文档中有关对象类的信息

object作为静态成员的主机

通常,您需要一个object来保存无需首先实例化某个类的实例即可使用的方法和值 / 变量。这种用法与 Java 中的static

object A {
  def twice(i: Int): Int = 2*i
}

然后,您可以使用A.twice(2)调用上述方法。

如果twice是某个类A的成员,那么您需要首先创建一个实例:

class A() {
  def twice(i: Int): Int = 2 * i
}

val a = new A()
a.twice(2)

您可以看到这是多么冗余,因为twice不需要任何特定于实例的数据。

object作为特殊的命名实例

您也可以将object本身用作类或特征的某些特殊实例。执行此操作时,您的对象需要扩展某些trait以使其成为其子类的实例。

考虑以下代码:

object A extends B with C {
  ...
}

BC的匿名(不可访问)类,并实例化名为A的此类的单个实例。

这意味着A可以传递给期望对象的类型为BC函数,或者将B with C传递给 C 的函数。

object附加功能

Scala 中还存在一些对象的特殊功能。我建议阅读官方文档

class是定义,描述。它根据方法和其他类型的组成来定义类型。

object是单例 - 保证是唯一的类的实例。对于object ,都会创建一个匿名类,该匿名类继承自您声明要实现的object从 Scala 源代码无法看到该类 - 尽管您可以通过反射来了解它。

objectclass之间有关系。如果对象共享相同的名称,则称它们为类的伴侣对象。发生这种情况时,每个人都可以访问另一个人private但是,这些方法不会自动导入。您要么必须显式地导入它们,要么用类 / 对象名作为前缀。

例如:

class X {
  // class X can see private members of object X
  // Prefix to call
  def m(x: Int) = X.f(x)

  // Import and use
  import X._
  def n(x: Int) = f(x)

  private def o = 2
}

object X {
  private def f(x: Int) = x * x

  // object X can see private members of class X
  def g(x: X) = {
    import x._
    x.o * o // fully specified and imported
   }
}

一个对象只有一个实例(您不能调用new MyObject )。您可以有一个类的多个实例。

对象具有Java 中的静态方法和字段相同(和一些其他)目的。