- 包可以像內部類那樣嵌套
- 包路徑不是絕對路徑
- 包聲明鏈x.y.z不自動將中間包x和x.y變成可見
- 文件頂部不帶花括號的包聲明在整個文件範圍內有效
- 包對象可以持有函數和變量
- 引入語句可以引入包、類和對象
- 引入語句可以出現在任何位置
- 引入語句可以重命名和隱藏特定成員
- java.lang、scala和Predef總是被引入
包
- 作用:管理大型程序的名稱
- 例如scala.collection.mutable.Map和scala.collection.immutable.Map位於不同的包
- 包可以包含在包語句中
- 同一個包可以定義在多個文件中
- 同一個文件可以多個包
// Employee.scala
package com{
package horstman{
package impatient{
class Employee{
val name = "及時雨宋江"
}
}
}
}
object Emplo extends App{
val a = new com.horstman.impatient.Employee
println(a.name)
val b = new com.horstman.impatient.Manager
println(b.emperor)
}
//Manage.scala,當然下面的內容放在Employee.scala中也沒有問題
package com{
package horstman{
package impatient{
class Manager{
val emperor = "宋徽宗"
}
}
}
}
作用域規則
- 對於嵌套包語句,可以訪問上層作用域的名稱,不帶包名,直接用
- 例如Employee可以訪問Utils,如果Utils放在com包中,也是可以訪問的
- scala中,包名是相對的,任何人可以在任何時候向任何包添加內容
- scala的自帶的包的絕對路徑:_root_.scala.******(root左右兩邊各一個下劃線)
package com{
package horstman{
package impatient{
class Employee(var salary:Double){
def giveRaise(rate:Double): Unit ={
salary += Utils.percentOf(salary,rate)
}
}
}
}
}
package com{
package horstman {
object Utils{
def percentOf(value:Double,rate:Double): Double = value*rate/100
}
}
}
object Emplo extends App{
val a = new com.horstman.impatient.Employee(10000)
a.giveRaise(40)
println(a.salary)
//14000.0
}
串聯式包語句
- 包語句可以包含一個串,或者說路徑區段
- 例如com.horstman.impatient中的Person不能直接使用Utils訪問,必須先引入包再訪問或者直接使用包的絕對路徑com.horstman.Utils
package com{
package horstman {
object Utils{
def percentOf(value:Double,rate:Double): Double = value*rate/100
}
}
}
//import _root_.scala.collection.mutable
package com.horstman.impatient{
package people{
class Person{
import com.horstman.Utils
Utils.percentOf(10,2)
}
}
}
文件頂部標記法
- 前面介紹的使用花括號的嵌套標記法,此外還可以在文件頂部使用package語句,不帶花括號,作用域爲整個文件
- 例如下面,文件的所有內容都屬於com.horstman.impatient
package com.horstman.impatient
package people
class Person
相當於
package com.horstman.impatient{
package people{
class Person
}
}
包對象
- 包可以包含類、對象和特質,但不能包含函數或變量
- 每個包(package B)都可以有一個包對象(package object B),需要在父包(package A)中定義,且名稱與子包一樣(都是B)
- 例如下面的com.horstman.impatient包下有一個子包people和包對象people
package com.horstman.impatient
//一個包對象與子包people同名
package object people{
val defaultName = "John"
}
//子包 people
package people{
class Person2{
var name = defaultName
}
}
//運行一下
object Manage extends App{
val a = new people.Person2
println(a.name)
//輸出John
}
包可見性
- 限制一個類成員在哪個包可以被訪問,private[包名] +類成員
package com.horstman.impatient.people
class Person{
private[people] def description = "A person"
}
引入
- 可以使用更短的名稱而不是長名稱,例如import java.awt.Color之後可以直接使用Color,如果不引入也可以直接使用長名稱
- 引入某個包的全部成員,使用下劃線,例如import java.awt._
- 引入類或對象的全部成員,import java.awt.Color._
- 任何地方都可以聲明引入,不僅限於文件頂部,import 語句的作用域一直到包含改語句的塊的末尾
- 引入放置在需要用的地方,可以減少可能的包衝突
引入時重命名和隱藏方法
- 選取:只引入包的幾個成員,使用選取器,放在花括號裏
import java.awt.{Color,Font}
- 重命名:使用=>
import java.util.{HashMap => JavaHashMap}
- 隱藏:將HashMap隱藏,導入剩餘的
import java.util.{HashMap => _ , _}
默認引入
- 默認引入下面的包
- scala開頭的包可以直接用
import java.lang._
import scala._
import Predef._