7 包和引入

  • 包可以像内部类那样嵌套
  • 包路径不是绝对路径
  • 包声明链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._
发布了75 篇原创文章 · 获赞 83 · 访问量 7万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章