【发布时间】:2010-12-17 20:11:07
【问题描述】:
我刚刚浏览了 Internet 上的一些 Scala 教程,并注意到在一些示例中,在示例开头声明了一个对象。
Scala 中的class 和object 有什么区别?
【问题讨论】:
我刚刚浏览了 Internet 上的一些 Scala 教程,并注意到在一些示例中,在示例开头声明了一个对象。
Scala 中的class 和object 有什么区别?
【问题讨论】:
一个对象恰好有一个实例(你不能调用new MyObject)。您可以拥有一个类的多个实例。
Object 与 Java 中的静态方法和字段具有相同(以及一些额外的)用途。
【讨论】:
class C 定义了一个类,就像在 Java 或 C++ 中一样。object O 创建一个 singleton 对象 O 作为某个匿名类的实例;它可用于保存与某些类的实例无关的静态成员。object O extends T 使对象 O 成为 trait T 的实例;然后,您可以在任何地方传递O,应该是T。class C,那么object C是C类的companion object;请注意,伴随对象不会自动成为C 的实例。另请参阅 object 和 class 的 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 {
...
}
此声明首先声明了一个匿名(不可访问)类,它同时扩展了B 和C,并实例化了一个名为A 的此类的单个实例。
这意味着 A 可以传递给期望类型为 B 或 C 或 B with C 的对象的函数。
object 的附加功能
Scala 中还存在一些对象的特殊功能。 我推荐阅读official documentation。
def apply(...) 启用 A(...) 的常用方法无名语法
def unapply(...) 允许创建自定义模式匹配 extractors
【讨论】:
Commerce 类,但 JVM 和 Java 语言会。 (这就是您可以执行object Foo{ def main(args:Seq[String]) } 并期望程序运行的方式。)
class 是一个定义,一个描述。它根据其他类型的方法和组合来定义一个类型。
object 是一个单例——一个保证唯一的类的实例。对于代码中的每个object,都会创建一个匿名类,它继承自您声明object 以实现的任何类。这个类不能从 Scala 源代码中看到——尽管你可以通过反射得到它。
object 和 class 之间存在关系。如果一个对象具有相同的名称,则称它们是一个类的伴生对象。发生这种情况时,每个人都可以访问对方的 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
}
}
【讨论】:
def f(x: X) = ???,那么它将能够调用伴生类X 的x 上的私有方法。
在 Scala 中定义一个对象就像在 Java 中定义一个只有静态方法的类。然而,在 Scala 中,一个对象可以扩展另一个超类,实现接口,并像一个类的实例一样被传递。 (所以它就像类上的静态方法,但更好)。
【讨论】:
形式上的区别——
用法上的区别:
object。您可以在有或没有相关类的情况下使用它。在第一种情况下,它被称为伴随对象。你必须:
要创建程序,您应该使用object 中的main 方法,而不是class。
object Hello {
def main(args: Array[String]) {
println("Hello, World!")
}
}
您也可以像在 java 中使用单例对象一样使用它。
【讨论】:
正如许多人所解释的,object 定义了一个单例实例。我认为这里的答案中被忽略的一件事是object 有多种用途。
它可以是 class/trait 的伴随对象,包含可能被视为静态方法或便利方法的对象。
它可以像模块一样工作,包含相关/附属类型和定义等。
它可以通过扩展一个class或一个或多个traits来实现一个接口。
它可以表示不包含数据的sealed trait 的情况。在这方面,它通常被认为比没有参数的case class 更正确。 sealed trait 只有 case object 实现者的特殊情况或多或少是枚举的 Scala 版本。
它可以作为implicit驱动逻辑的证据。
它引入了单例类型。
这是一个非常强大且通用的结构。 Scala 初学者可能会非常困惑的是,相同的结构可以有截然不同的用途。而object 可以同时服务于这些不同的用途,这可能会更加令人困惑。
【讨论】:
对象在某种程度上类似于Java中的静态类,静态特性意味着静态类在放到JVM中时不需要创建对象,可以直接使用它的类名和同一个实例(相同的数据状态)在任何地方共享。
【讨论】:
object 关键字创建了一个新的单例类型,它就像一个只有一个命名实例的class。如果您熟悉 Java,那么在 Scala 中声明一个 object 很像创建一个匿名类的新实例。
Scala 没有等效于 Java 的 static 关键字,并且 object 经常在 Scala 中使用,您可以在 Java 中使用具有静态成员的类。
【讨论】:
Object 是一个类,但它已经有一个实例,所以你不能调用new ObjectName。另一方面,Class 只是类型,它可以通过调用new ClassName() 成为实例。
【讨论】:
Scala 类与 Java 类相同,但 scala 没有为您提供类中的任何入口方法,如 java 中的 main 方法。与对象关键字关联的主要方法。您可以将 object 关键字视为创建隐式定义的类的单例对象。
【讨论】:
在 Scala 中,没有 static 的概念。因此 scala 创建了一个单例对象来为您的程序执行提供入口点。
如果您不创建单例对象,您的代码将成功编译,但不会产生任何输出。在 Singleton Object 中声明的方法可以全局访问。单例对象可以扩展类和特征。
Scala 单例对象示例
object Singleton{
def main(args:Array[String]){
SingletonObject.hello() // No need to create object.
}
}
object SingletonObject{
def hello(){
println("Hello, This is Singleton Object")
}
}
输出:
Hello, This is Singleton Object
在scala中,当你有一个与单例对象同名的类时,它被称为伴生类,单例对象被称为伴生对象。
伴生类和它的伴生对象都必须在同一个源文件中定义。
Scala 伴随对象示例
class ComapanionClass{
def hello(){
println("Hello, this is Companion Class.")
}
}
object CompanoinObject{
def main(args:Array[String]){
new ComapanionClass().hello()
println("And this is Companion Object.")
}
}
输出:
Hello, this is Companion Class.
And this is Companion Object.
在scala中,一个类可以包含:
1.数据成员
2。成员方法
3。构造函数块
4.嵌套类
5.超类信息等
您必须初始化类中的所有实例变量。没有默认范围。如果您不指定访问范围,则它是公共的。必须有一个定义了 main 方法的对象。它为您的程序提供了起点。在这里,我们创建了一个类的示例。
Scala 类示例
class Student{
var id:Int = 0; // All fields must be initialized
var name:String = null;
}
object MainObject{
def main(args:Array[String]){
var s = new Student() // Creating an object
println(s.id+" "+s.name);
}
}
对不起,我来晚了,但我希望它能帮助你。
【讨论】:
如果你是java背景,scala中类的概念有点类似于Java,但是scala中的类不能包含静态成员。
scala 中的对象是单例类型,您可以使用对象名称在其中调用方法,scala 中的对象是关键字,而 java 中的对象是类的实例
【讨论】:
一个类就像其他语言中的任何其他类一样。您可以像定义任何其他语言一样定义类,但有一些语法差异。
class Person(val name: String)
val me = new Person("My name")
但是,object 是一个只有单个对象的类。这很有趣,因为它可以用于使用 companion 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 中使用单例对象所做的那样。
【讨论】: