我刚刚在互联网上浏览了一些Scala教程,并注意到在一些示例中,对象是在示例的开头声明的。

Scala中类和对象的区别是什么?


当前回答

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

对象与Java中的静态方法和字段具有相同的(以及一些额外的)用途。

其他回答

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

对象与Java中的静态方法和字段具有相同的(以及一些额外的)用途。

博士tl;

class C定义一个类,就像在Java或c++中一样。 object O创建一个单例对象O作为某个匿名类的实例;它可以用来保存与某些类的实例没有关联的静态成员。 对象O扩展了T,使对象O成为性状T的实例;你可以在任何地方传递O,期望传递T。 如果存在类C,则对象C是类C的伴生对象;注意,伴生对象并不自动是C的实例。

也可以参考Scala文档了解对象和类。

对象作为静态成员的宿主

大多数情况下,您需要一个对象来保存可用的方法和值/变量,而不必首先实例化某个类的实例。 这种用法与Java中的静态成员密切相关。

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不需要任何特定于实例的数据。

对象作为特殊的命名实例

您还可以使用对象本身作为类或trait的一些特殊实例。 当你这样做的时候,你的对象需要扩展一些特征,以成为它的一个子类的实例。

考虑下面的代码:

object A extends B with C {
  ...
}

该声明首先声明了一个匿名(不可访问)类,它扩展了B和C,并实例化了这个类的一个名为a的实例。

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

对象的附加特征

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

def apply(…)启用A(…)常用的无方法名语法 Def unapply(…)允许创建自定义模式匹配提取器 如果伴随同名的类,则对象在解析隐式参数时承担特殊角色

Scala类和Java类一样,但是Scala没有在类中提供任何入口方法,就像Java中的main方法一样。与object关键字关联的主要方法。可以将object关键字视为创建隐式定义的类的单例对象。

更多信息请查看这篇文章 scala编程中的类和对象关键字

类就像其他语言中的任何其他类一样。定义类就像任何其他语言一样,只是在语法上有所不同。

class Person(val name: String)
val me = new Person("My name")

然而,object是一个只有单个对象的类。这使得它很有趣,因为它可以用于使用伴生对象创建类的静态成员。这个伴随对象可以访问类定义的私有成员,并且它与您正在定义的类具有相同的名称。

class Person(var name: String) {

  import Person._

  def hi(): String = sayHello(name)
}

object Person {
  private def sayHello(name: String): String = "Hello " + name
}

val me = new Person("My name")
me.hi()

另外,值得注意的一点是对象类是惰性创建的,这是另一个重要的点。除非在代码中需要,否则这些不会被实例化。

如果您正在为JDBC定义连接创建,您可以在对象内部创建它们以避免重复,就像我们在Java中对单例对象所做的那样。

正如许多人所解释的,object定义了一个单例实例。在这里的答案中,我认为有一件事被遗漏了,那就是对象有几个用途。

It can be the companion object to a class/trait, containing what might be considered static methods or convenience methods. It can act much like a module, containing related/subsidiary types and definitions, etc. It can implement an interface by extending a class or one or more traits. It can represent a case of a sealed trait that contains no data. In this respect, it's often considered more correct than a case class with no parameters. The special case of a sealed trait with only case object implementors is more or less the Scala version of an enum. It can act as evidence for implicit-driven logic. It introduces a singleton type.

这是一个非常强大和普遍的结构。Scala初学者可能非常困惑的是,相同的构造可能有截然不同的用途。一个物体可以同时用于多种不同的用途,这可能会更令人困惑。