Scala包的作用(和Java一样),区分相同名字的类,当类很多时,很好的管理类,控制访问范围, 对类的功能进行扩展。
1.语法
package 包名
命名规范:
一般是小写字母+小圆点一般是
com.公司名.项目名.业务模块名
比如:com.blueicex.project.model1
2.基本形式(感性认识)
package com.boke{} 表示创建了包 com.boke ,在{}中// 继续写它的子包 scala //com.boke.scala, 还写类,特质trait,还写object。在一个文件中,同时创建多个包,以及给各个包创建类,trait和object。
MotionKonwlege.scala
package com.blueicex.learn.packagelearn
/**
* @author blueicex
* @date 2020/2/16 15:01
* @projectname test
* @Mem learn
*/
object Motionknowledge {
def main(args: Array[String]): Unit = {
import com.blueicex.temp._
var test = new Test
println(test)
}
}
//只能在同一个文件中使用这种自定义的包,并且这种自动的包不产生路径
package com.blueicex.temp {
class Test {
override def toString: String = super.toString
}
}
3.包作用域
包可以直接向上访问,即Scala中子包中直接访问父包的内容,大括号体现作用域。(Java中子包使用父包的类,需要import)。在子包和父包类重名时,默认采用就近原则,如果希望指定使用某个类,则带上包名,父包要访问子包的内容时,需要import对应的类等,可以在同一个.scala文件中声明多个并列的package(建议嵌套的package不要超过3层)。包名可以相对也可以绝对,比如访问 BeanProperty 的绝对路径是: root.scala.beans.BeanProperty,在一般情况下,我们使用相对路径来引入包,只有当包名冲突时,使用绝对路径来处理。
PackageWorkArea.scala
package com.blueicex.learn.packagelearn
import scala.beans.BeanProperty
/**
* @author Administrator blueicex
* @date 2020/2/16 15:25
* @projectname test
* @Mem learn
*/
object PackageWorkArea {
//全局引用包
@BeanProperty
var param1: Int = _
//绝对引用包
@scala.beans.BeanProperty
var param2: Int = _
//相对引用包
@beans.BeanProperty
var param3: Int = _
}
4.包对象
包可以包含类、对象和特质(trait),但不能包含函数/方法或变量的定义。这是Java虚拟机的局限。为了弥补这一点,Scala提供了包对象的概念来解决这个问题。在包中直接写方法,或者定义变量,就错误,使用包对象的技术来解决。package object scala表示创建一个包对象scala, 它是com.boke.scala这个包对应的包对象。每一个包都可以有一个包对象。包对象的名字需要和子包一样。在包对象中可以定义变量,方法。在包对象中定义的变量和方法,就可以在对应的包中使用。 在底层这个包对象会生成两个类 package.class 和 package$.class。 包对象名称需要和包名一致,一般用来对包的功能补充。
package com.boke {
//创建包对象
package object scala {
var name = "king"
def sayHiv(): Unit = {
println("package object scala sayHI~")
}
}
//创建的包
//与包对象同名
package scala {
class Person {
val name = "Nick"
def play(message: String): Unit = {
println(this.name + " " + message)
}
}
class User {
def testUser(): Unit = {
println("name = " + name)
sayHiv()
}
}
// 创建在包scala中创建执行对象Test1
object Test1 {
def main(args: Array[String]): Unit = {
println("name=" + name)
name = "yy"
sayHiv()
println(com.boke.scala.name)
val user = new com.boke.User()
println("user" + user)
}
}
}
}
5.伴生类、伴生对象及访问修饰符
伴生类、伴生对象
在类的同一层次上,同时出现同名的class和object,那么class为伴生类,obejct为伴生对象,因为Scala没有static, 所以设计伴生类和伴生对象,伴生类内写非静态的内容,伴生对象写静态内容
访问修饰符
属性访问权限为默认时,从底层看属性是private的,但是因为提供了xxx_$eq()[类似setter]/xxx()[类似getter]方法,因此从使用效果看是任何地方都可以访问。默认为public访问权限,private为私有权限,只有在类的内部和伴生对象中可用,protected只能子类访问,同包无法访问。 在Scala中没有public关键字,即不能用public显示的修饰属性和方法。
包访问权限(表示属性有了限制,同时包也有了限制),这点和Java不一样,java没有包访问修饰限制,体现出Scala包的灵活性。
package com.scala.exercise
class Person {
//增加包访问权限后
//1.private同时起作用,不仅同类可以使用
//2.com.scala.exercise中包下的其它类也可以使用
private[exercise] val name = "Jack"
//当然,也可以将可见度延展到上层包
private[scala] val age = 23
//说明:private可以变化,比如protected[scala],非常的灵活
}
object boke_demo01 {
def main(args: Array[String]): Unit = {
val c = new Clerk()
c.showInfo()
Clerk.test(c)
}
}
//类
class Clerk {
var name: String = "jack" //
private var sal: Double = 9999.9
protected var age = 23
var job: String = "大数据工程师"
def showInfo(): Unit = {
//在本类可以使用私有的
println(" name " + name + " sal= " + sal)
}
}
object Clerk {
def test(c: Clerk): Unit = {
//这里体现出在伴生对象中,可以访问c.sal
println("test() name=" + c.name + " sal= " + c.sal)
}
}
class Person {
//这里我们增加一个包访问权限
//下面private[scala] : 1,仍然是private 2. 在scala包(包括子包)下也可以使用name ,相当于扩大访问范围
protected[scala] val name = "Jack"
}
6.包的引入
在Scala中,import语句可以出现在任何地方,并不仅限于文件顶部,import语句的作用一直延伸到包含该语句的块末尾。
Java中如果想要导入包中所有的类,可以通过通配符*,Scala中采用_(下划线)。
import scala.collection.mutable._
如果不想要某个包中全部的类,而是其中几个类,可以采用选取器(大括号)。
import scala.collection.mutable.{HashMap, HashSet}
如果引入的多个包中含有相同的类,那么可以将不需要的类进行重命名进行区分
import java.util.{HashMap => JavaHashMap}
如果某个冲突的类根本就不会用到,那么这个类可以直接隐藏掉。
import java.util.{ HashMap=>_, _} // 含义为 引入 java.util 包的所有类,但是忽略 HahsMap 类
————Blueicex 2020/2/15 18:06 blueice1980@126.com