scala支持两种package的定义方法:
package com
{
package tedneward
{
package scala
{
package demonstration
{
object App
{
def main(args : Array[String]) : Unit =
{
System.out.println("Howdy, from packaged code!")
args.foreach((i) => System.out.println("Got " + i) )
}
}
}
}
}
}
package com.tedneward.scala.demonstration
{
object App
{
def main(args : Array[String]) : Unit =
{
System.out.println("Howdy, from packaged code!")
args.foreach((i) => System.out.println("Got " + i) )
}
}
}
我喜欢第二个人,看起来清爽
import的规则:
(1)可以出现在源代码的任意地方:
package com
{
package tedneward
{
package scala
{
// ...
package mathfun
{
object App
{
<span style="background-color: rgb(192, 192, 192);">import java.math.BigInteger</span>
def factorial(arg : BigInteger) : BigInteger =
{
if (arg == BigInteger.ZERO) BigInteger.ONE
else arg multiply (factorial (arg subtract BigInteger.ONE))
}
def main(args : Array[String]) : Unit =
{
if (args.length > 0)
System.out.println("factorial " + args(0) +
" = " + factorial(new BigInteger(args(0))))
else
System.out.println("factorial 0 = 1")
}
}
}
}
}
}
访问控制:
打包(和导入)是 Scala 封装的一部分,和在 Java 代码中一样,在 Scala 中,打包很大一部分在于以选择性方式限定访问特定成员的能力 — 换句话说,在于 Scala 将特定成员标记为 “公有(public)”、“private(私有)” 或介于两者之间的成员的能力。
Java 语言有四个级别的访问:公有(public)、私有(private)、受保护的(protected )和包级别(它没有任何关键词)访问。Scala:
- 废除了包级别的限制(在某种程度上)
- 默认使用 “公有”
- 指定 “私有” 表示 “只有此作用域可访问”
相反,Scala 定义 “protected” 的方式与在 Java 代码中不同;Java protected 成员对于子类和在其中定义成员的包来说是可访问的,Scala 中则仅有子类可访问。这意味着 Scala 版本的 protected 限制性要比 Java 版本更严格(虽然按理说更加直观)。
然而,Scala 真正区别于 Java 代码的地方是 Scala 中的访问修饰符可以用包名来 “限定”,用以表明直到 哪个访问级别才可以访问成员。例如,如果 BizarroMath
包要将成员访问权限授权给同一包中的其他成员(但不包括子类):
package com
{
package tedneward
{
package scala
{
// ...
package mathfun
{
object BizarroMath
{
def bizplus(a : Int, b : Int) = { a - b }
def bizminus(a : Int, b : Int) = { a + b }
def bizmultiply(a : Int, b : Int) = { a / b }
def bizdivide(a : Int, b : Int) = { a * b }
<span style="background-color: rgb(192, 192, 192);"> private[mathfun] def bizexp(a : Int, b: Int) = 0</span>
}
}
}
}
}
注意此处的 private[mathfun]
表达。本质上,这里的访问修饰符是说该成员直到 包 mathfun
为止都是私有的;这意味着包 mathfun
的任何成员都有权访问 bizexp
,但任何包以外的成员都无权访问它,包括子类。
这一点的强大意义就在于任何包都可以使用 “private” 或者 “protected” 声明甚至 com
(乃至 _root_
,它是根名称空间的别名,因此本质上private[_root_]
等效于 “public” 同)进行声明。这使得 Scala 能够为访问规范提供一定程度的灵活性,远远高于 Java 语言所提供的灵活性。
实际上,Scala 提供了一个更高程度的访问规范:对象私有 规范,用 private[this]
表示,它规定只有被同一对象调用的成员可以访问有关成员,其他对象里的成员都不可以,即使对象的类型相同(这弥合了 Java 访问规范系统中的一个缺口,这个缺口除对 Java 编程问题有用外,别无他用。)
注意访问修饰符必须在某种程度上在 JVM 之上映射,这致使定义中的细枝末节会在从正规 Java 代码中调用或编译时丢失。例如,上面的 BizarroMath 示例(用 private[mathfun]
声明的成员 bizexp
)将会生成清单 9 中的类定义(当用 javap 来查看时):
apply的使用?