1.包/作用域
在Java和Scala中管理项目可以使用包结构,C和C#使用命名空间。
对于package,有如下几种形式:
形式体现:
package com.nick.impatient.people
class Person{
val name = "Nick"
def play(message: String): Unit ={
}
}
等同于:
package com.nick.impatient
package people
class Person{
val name = "Nick"
def play(message: String): Unit ={
}
}
等同于:
package com.nick.impatient{// com和com.nick的成员在这里不可见
package people{
class Person{
val name = "Nick"
def play(message: String): Unit ={
}
}
}
}
注:位于文件顶部不带花括号的包声明在整个文件范围内有效。
通过以上形式,发出总结:
(1)包也可以像内部类那样嵌套,作用域原则:可以直接向上访问。即,子package中直接访问父package中的内容。(即:作用域)
(2)包对象可以持有函数和变量
(3)引入语句可以引入包、类和对象
(4)源文件的目录和包之间并没有强制的关联关系
(5)可以在同一个.scala文件中,声明多个并列的package
(6)包名可以相对也可以绝对,比如,访问ArrayBuffer的绝对路径是:_root_.scala.collection.mutable.ArrayBuffer
2.包对象
包可以包含类、对象和特质trait,但不能包含函数或变量的定义。很不幸,这是Java虚拟机的局限。把工具函数或常量添加到包而不是某个Utils对象,这是更加合理的做法。包对象的出现正是为了解决这个局限。每个包都可以有一个包对象。你需要在父包中定义它,且名称与子包一样。
package com.nick.impatient
package object people {
val defaultName = "Nick"
}
package people {
class Person {
var name = defaultName // 从包对象拿到的常置
}
}
3.包可见性
在Java中,没有被声明为public、private或protected的类成员在包含该类的包中可见。在Scala中,你可以通过修饰符达到同样的效果。以下方法在它自己的包中可见:
package com.nick.impatient.people
class Person {
private[people] def description="人的名字:" + name
}
当然,也可以将可见度延展到上层包:
private[impatient] def description="人的名字:" + name
4.引入
在Scala中,import语句可以出现在任何地方,并不仅限于文件顶部。import语句的效果一直延伸到包含该语句的块末尾:这是个很有用的特性,尤其是对于通配引入而言。从多个源引入大量名称总是让人担心。事实上,有些Java程序员特别不喜欢通配引入,以至于从不使用这个特性,而是让IDE帮他们生成一长串引入语句。通过将引入放置在需要这些引入的地方,你可以大幅减少可能的名称冲突。
5.重命名和隐藏方法
(1) 重命名:
如果你想要引人包中的几个成员,可以像这样使用选取器( selector),而且选取的同时,可以重命名:
import java.util.{ HashMap=>JavaHashMap, List}
import scala.collection.mutable._
这样一来,JavaHashMap就是java.utiI.HashMap,而HashMap则对应scala.collection.mutable.HashMap。
(2)隐藏:
选取器HashMap =>_将隐藏某个成员而不是重命名它。这仅在你需要引入其他成员时有用:
import java.util.{HashMap=>_, _ }
import scala.collection.mutable._
现在,HashMap很明确的便指向了scala.collection.mutable.HashMap,因为java.util.HashMap被隐藏起来了。
注:
每个Scala程序都隐式地以如下代码开始:
import java.lang._
import scala._
import Predef._
和Java程序一样,java.lang总是被引入。接下来,scala包也被引入,不过方式有些特殊。不像所有其他引入,这个引入被允许可以覆盖之前的引入。举例来说,scala.StringBuilder覆盖java.lang.StringBuilder而不是与之冲突。最后,Predef对象被引入。它包含了相当多有用的函数,这些同样可以被放置在scala包对象中,不过Predef在Scala还没有加入包对象之前就存在了。
由于scala包默认被引入,对于那些以scala开头的包,你完全不需要写全这个前缀。例如:
collection.mutable.HashMap
上述代码和以下写法一样好:
scala.collection.mutable. HashMap
6.源码详见:https://github.com/luomingkui/scala