1、Scala的包和Java中的包的目的是相同的:管理大型程序中的名称,与对象或类的定义不同,同一个包可以定义在多个文件当中
a.scala
package a{
package b{
package c{
class A{
}
}
}
}
b.scala
package a{
package b{
package c{
class B{
}
}
}
}
2、包嵌套、包对象
object PackageB {
def main(args: Array[String]): Unit = {
new A()
val b = new B("jack")
b.say //输出: 2016-12-23:Hello!jack
new D()
new W()
}
}
/**
* 1、同一个包可以定义在多个文件当中
* 2、源文件的目录和包之间并没有强制的关联关系。你不需要将PackageB.scala和PackageA.scala放在com/aralbox/p目录当中
* 换个角度讲,你也可以在同一个文件当中为多个包贡献内容,而java来说是强制源文件的目录和包一致
* 3、同时在同意个源文件中可以定义多个包
*/
package a{
import java.text.SimpleDateFormat
import java.util.Date
//a.b包下的包对象
package object b{
def nowTime:String = {
val fomart = new SimpleDateFormat("yyyy-MM-dd HH:mi:ss")
fomart.format(new Date)
}
}
package b{
object Utils {
//包嵌套 包下面的子包都能直接访问 不需要写全名
def now:String = {
val fomart = new SimpleDateFormat("yyyy-MM-dd")
fomart.format(new Date)
}
}
/**
* 包对象
* 1、包可以包含类、对象和特质,但不能包含函数或变量的定义。很不幸,这是Java虚拟机的局限
* 2、把工具函数或常量添加到包而不是某个Utils对象,这是更加合理的做法
* 3、包对象的出现正是为了解决这个局限。每个包都可以有一个包对象。你需要在父包中定义它,且名称与子包一样
* 4、包对象被编译成带有静态方法和字段的JVM类,名为package.class,位于相应的包下a.b
* 5、在JVM中,你可以使用package作为类名。对源文件使用相同的命名规则是好习惯,可以把包对象放到文件a/b/package.scala。
* 这样一来,任何人想要对包增加函数或变量的话,都可以以很容易地找到对应的包对象
*/
package object c{
def now:String = {
val fomart = new SimpleDateFormat("yyyy-MM-dd")
fomart.format(new Date)
}
}
package c{
//类也可以申明类的可见范围 那么在a.b下面的类都可以直接使用B类 因为是private 那么不是此包下面的是不能访问的
protected [p] class B(name:String){
/**
* 在Java中,没有被声明为public、private或protected的类成员在包含该类的包中可见。在Scala中,你可以通过修饰符达到同样的效果
* 这样age 只能在a.b.c包中可见
*/
private[c] var age:Int = 20
//你可以将可见度延展到上层包a.b
private[b] var height:Int = 170
//使用父包的对象的方法
def say = println(Utils.now +":Hello!"+name)
//使用包对象的方法
def packageObjSay = println(now +":Hello!"+name)
//父类包的包对象 在子包下都可以直接访问
def prentObjSay = println(nowTime +":Hello!"+name )
}
class Cinner{
def compare(b:B):Boolean = {
b.age > 19
}
}
}
//Couter在a.b下面
class Couter{
def compare(b:B):Boolean = {
//b.age //这样就访问不到 因为类Couter不在a.b.c包内
b.height > 180 // 因为height的可见范围是a.b下面
}
}
}
// W的包路径是a
class W{
def say = println(a.b.nowTime) // 如果不在a.b(包含)下的类就不能直接使用nowTime访问包对象的field和方法 必须要加上路径名称才能访问
}
}
/**
* 包冲突
*/
package a{
package b{
package d{
class D{
def say = {
// collection实际是在scala.collection,因为scala隐身引入了scal._ 所以这个省略了
//val buf = new collection.mutable.ArrayBuffer[String]
val buf = _root_.scala.collection.mutable.ArrayBuffer[String]("1")
}
}
}
/**
* 如果这个时候在a.b下增加子包collection 那么class D中就会引用com.aralbox.p.a.b.collection
* 在Java中,这个问题不会发生,因为包名总是绝对的
* 但是在Scala中,包名是相对的,就像内部类的名称一样。
* 内部类通常不会遇到这个问题,因为所有代码都在同一个文件当中,由负责该文件的人直接控制。
* 但是包不一样,任何人都可以在任何时候向任何包添加内容
* 解决方法一: 使用绝对包名,以_root_
* _root_.scala.collection.mutable.ArrayBuffer[String]
* 解决方法二: "串联式"包语句
*
*/
package collection{
}
}
}
/**
* "串联式"包语句
*/
package a.b.d{ // 对于类G来说 a、a.b包下的成员在这里就不可见
package g{
class G{
def say = {
//这样的包语句限定了可见的成员。现在com.aralbox.p.a.b.collection包不再能够以collection访问到了
val buf = new collection.mutable.ArrayBuffer[String]
buf + "a"
buf +: "c"
}
}
}
}
3、包引用
/**
* 引入语句
* 1、_通配符 这和Java中的通配符*一样。在Scala中,*是合法的标识符。你完全可以定义com.horstmann.*.people这样的包,但请别这样做
* 2、隐式引入 每个Scala程序都隐式地以如下代码开始
* import java.lang._
import scala._
import Predef._
* 3、选取器HashMap =>_将隐藏某个成员而不是重命名它
* 4、List => JavaList //重名List 为 JavaList
*/
import java.awt._
import java.util.{
HashMap => _,
List => JavaList
}
参考 http://www.cnblogs.com/sunddenly/p/4436897.html