Scala 伴生对象不是单例
Scala companion objects are not singleton
我有以下两个类。
class A (name: String) {
}
object A {
}
根据单例的定义,我们只能有一个该类型的对象。但是,我可以使用以下代码创建两个类型为 A
的不同对象。
object B {
def main(args: Array[String]): Unit = {
val a = new A("Vinod")
println(a)
val b = new A("XYZ")
println(b)
}
}
谁能解释一下,我的理解哪里不对?
可以将伴随对象视为 class 的静态 space。如果你想让 A 成为一个单例,你可以把它变成一个对象而不是 class
new A
指的是 class A
(不是单例),而不是 object A
。您可以轻松检查它:如果删除 class A
,new A
行将不再编译。
另请注意 object
并非 必然 单例:它们可以嵌套在 类 或特征中,在这种情况下有一个用于外部类型的每个实例。
伴生对象不是伴生对象的实例 class。他们甚至不是同一种类型。
class A
object A {
var state = 0
def update() :Unit = state = state + 1
}
val abc :A = new A //instance of class A
val xyz :A.type = A //2nd reference to object A
// both reference the same singleton object
xyz.update() //res0: Unit = ()
A.state //res1: Int = 1
abc.state //Error: value state is not a member of A$A2521.this.A
一个object
本身是一个单例。它有自己的 class 并且在运行时不存在相同 class 的其他实例。
但是,您在这里描述的模式是不同的:object A
是 不是 class A
的实例,除非您这样做使用 object A extends A
。您可以通过将 class A
设为 sealed
class 使其成为 class A
的唯一实例,但这在几乎所有情况下都是不必要的.
如果您真的想要单例模式,请删除 class
并仅使用 object A
,它的所有成员都将是 "static" 意义上的 Java。
注意object A
的实际类型可以参考A.type
,默认情况下与类型A
完全无关if class A
存在。同样,A.type
可以 是 A
的子类型,如果你明确地这样做的话。
我有以下两个类。
class A (name: String) {
}
object A {
}
根据单例的定义,我们只能有一个该类型的对象。但是,我可以使用以下代码创建两个类型为 A
的不同对象。
object B {
def main(args: Array[String]): Unit = {
val a = new A("Vinod")
println(a)
val b = new A("XYZ")
println(b)
}
}
谁能解释一下,我的理解哪里不对?
可以将伴随对象视为 class 的静态 space。如果你想让 A 成为一个单例,你可以把它变成一个对象而不是 class
new A
指的是 class A
(不是单例),而不是 object A
。您可以轻松检查它:如果删除 class A
,new A
行将不再编译。
另请注意 object
并非 必然 单例:它们可以嵌套在 类 或特征中,在这种情况下有一个用于外部类型的每个实例。
伴生对象不是伴生对象的实例 class。他们甚至不是同一种类型。
class A
object A {
var state = 0
def update() :Unit = state = state + 1
}
val abc :A = new A //instance of class A
val xyz :A.type = A //2nd reference to object A
// both reference the same singleton object
xyz.update() //res0: Unit = ()
A.state //res1: Int = 1
abc.state //Error: value state is not a member of A$A2521.this.A
一个object
本身是一个单例。它有自己的 class 并且在运行时不存在相同 class 的其他实例。
但是,您在这里描述的模式是不同的:object A
是 不是 class A
的实例,除非您这样做使用 object A extends A
。您可以通过将 class A
设为 sealed
class 使其成为 class A
的唯一实例,但这在几乎所有情况下都是不必要的.
如果您真的想要单例模式,请删除 class
并仅使用 object A
,它的所有成员都将是 "static" 意义上的 Java。
注意object A
的实际类型可以参考A.type
,默认情况下与类型A
完全无关if class A
存在。同样,A.type
可以 是 A
的子类型,如果你明确地这样做的话。