发布于 2011-01-13 08:09:49
在2.8之前,您必须在包和对象之间进行选择。包的问题是它们不能单独包含方法或值。所以你必须把所有的东西都放进另一个物体里,这会很尴尬。观察:
object Encrypt {
private val magicConstant = 0x12345678
def encryptInt(i: Int) = i ^ magicConstant
class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] {
def hasNext = ii.hasNext
def next = encryptInt(ii.next)
}
}
现在您可以import Encrypt._
并访问方法encryptInt
以及类EncryptIterator
。手巧!
相比之下,
package encrypt {
object Encrypt {
private[encrypt] val magicConstant = 0x12345678
def encryptInt(i: Int) = i ^ magicConstant
}
class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] {
def hasNext = ii.hasNext
def next = Encrypt.encryptInt(ii.next)
}
}
这并没有太大的不同,但它使用户同时导入了encrypt._
和encrypt.Encrypt._
,或者不得不一遍又一遍地编写Encrypt.encryptInt
。为什么不像第一种模式那样只使用对象呢?(实际上不存在性能损失,因为嵌套类实际上并不是幕后的Java内部类;据JVM所知,它们只是常规类,但是有一些花哨的名称,告诉您它们是嵌套的。)
在2.8中,你也可以吃蛋糕:把这个东西叫做包对象,编译器会为你重写代码,这样它实际上看起来就像引擎盖下的第二个例子(除了Encrypt
实际上在内部被称为package
),但是在名称空间方面,它的行为就像第一个例子--就命名空间而言--这些值和防御程序就在那里,而不需要额外的导入。
因此,在2.8之前启动的项目通常使用对象来封装大量的东西,就像它们是一个包一样。在2.8之后,主要动机之一已被删除。(但要明确的是,使用对象仍然没有坏处;更重要的是它在概念上具有误导性,而不是它对性能或诸如此类的负面影响。)
(请注意,请不要试图用这种方式加密任何东西,除非是作为一个例子或一个笑话!)
发布于 2011-01-13 07:48:12
当您想要使用抽象类型变量时,有时需要在对象中放置类、特征和对象,请参见类型
发布于 2011-01-13 06:50:47
两者都可以。除其他外,内部类/特性的实例可以访问其父类的变量。内部类必须使用父实例创建,父实例是外部类型的实例。
在其他情况下,它可能只是将密切相关的事情分组的一种方式,如您的object
示例所示。注意,特征LocParam
是密封的,这意味着所有子类都必须位于同一个编译单元/文件中。
https://stackoverflow.com/questions/4681323
复制