编程那点事编程那点事

专注编程入门及提高
探究程序员职业规划之道!

package与import

为什么要有package的概念?

  • 因为要对多个同名的类进行命名空间的管理,避免同名类发生冲突

  • 比如说,scala.collection.mutable.Map和scala.collection.immutable.Map

package定义

  • package定义的第一种方式: 多层级package定义(比较差的做法,一般不这么干)

package com {
package ibeifeng {
package scala {
class Test {}
}
}
}
  • package定义的第二种方式: 串联式package定义(也不怎么样,一般也不这么干)

package com.ibeifeng.scala {
package service {
class Test {}
}
}
  • package定义的第三种方式: 文件顶部package定义

package com.ibeifeng.scala.service
class Test {
}
  • package定义的第四种方式: IDE自动生成包

package特性

  • package特性一: 同一个包定义,可以在不同的scala源文件中的; 一个scala源文件内,可以包含两个包

// Test1.scala
package com {
package ibeifeng {
package scala {
class Test1
}
}
}
// Test2.scala
package com {
package ibeifeng {
package scala {
class Test2
}
}
}
// Test3.scala
package com {
package ibeifeng {
package scala1 {
class Test
}
}
}
package com {
package ibeifeng {
package scala2 {
class Test
}
}
}
  • package特性二: 子包中的类,可以访问父包中的类

//  Test.scala
package com {
package ibeifeng {
package scala {
object Utils {
def isNotEmpty(str: String): Boolean = str != null && str != ""
}
class Test
package service {
class MyService {
def sayHello(name: String) {
if(Utils.isNotEmpty(name)) {
println("Hello, " + name)
} else {
println("Who are you?")  
}
}
}
}
}
}
}
object MainClass {
  def main(args: Array[String]): Unit = {
    val service = new com.ibeifeng.scala.service.MyService
    service.sayHello("leo")  
    service.sayHello("")  
  }
}
  • package特性三: 相对包名与绝对包名

package com {
package ibeifeng {
package scala {
object Utils {
def isNotEmpty(str: String): Boolean = str != null && str != ""
}
class Test
package collection {}
package service {
class MyService {
// 这会报错,默认使用相对报名,从com.ibeifeng.scala.collection包中,寻找mutable包下的ArrayBuffer类
// 但是找不到,所以会报错
// val names = new scala.collection.mutable.ArrayBuffer[String]
// 正确的做法是使用_root_,引用绝对包名
val names = new _root_.scala.collection.mutable.ArrayBuffer[String]
def sayHello(name: String) {
if(Utils.isNotEmpty(name)) {
println("Hello, " + name)
} else {
println("Who are you?")  
}
}
}
}
}
}
}
  • package特性四: 定义package对象(比较少)

    package内的成员,可以直接访问package对象内的成员

package com.ibeifeng.scala
package object service {
val defaultName = "Somebody"
}
package service {
class MyService {
def sayHello(name: String) {
if(name != null && name != "") {
println("Hello, " + name)
} else {
println("Hello, " + defaultName) 
}
}
}
}
  • package特性五: package可见性

package com.ibeifeng.scala
class Person {
private[scala] val name = "leo"
private[ibeifeng] val age = 25
}

import

  • 如果没有import,那么。。。你每次创建某个包下的类的对象,都得用new com.ibeifeng.scala.service.MyService这种冗长的格式

  • 如果用了import,只要先import com.ibeifeng.scala.service.MyService,然后再new MyService,即可

import com.ibeifeng.scala.service.MyService;
object MainClass {
  def main(args: Array[String]): Unit = {
    val service = new MyService
    service.sayHello("leo")  
    service.sayHello("")  
  }
}

import特性

  • import特性一: 用import com.ibeifeng.scala.service._这种格式,可以导入包下所有的成员

  • import特性二: scala与java不同之处在于,任何地方都可以使用import,比如类内、方法内,这种方式的好处在于,可以在一定作用域范围内使用导入

object MainClass {
  def main(args: Array[String]): Unit = {
    import com.ibeifeng.scala.service._
    
    val service = new MyService
    service.sayHello("leo")  
    service.sayHello("")  
  }
}
  • import特性三: 选择器、重命名、隐藏

import com.ibeifeng.scala.service.{ MyService } // 仅仅导入com.ibeifeng.scala.service包下的MyService类
import com.ibeifeng.scala.service.{ MyService => MyServiceImpl } // 将导入的类进行重命名
import com.ibeifeng.scala.service.{ MyService => _, _ } // 导入com.ibeifeng.scala.service包下所有的类,但是隐藏掉MyServicep类
  • import特性四: 隐式导入

    每个scala程序默认都会隐式导入以下几个包下所有的成员

import java.lang._
import scala._
import Predef._


未经允许不得转载: package与import