开发者学堂课程【Scala 核心编程-基础:包的使用细节和注意事项1】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/609/detail/8956
包的使用细节和注意事项1
内容介绍:
一、scala 打包的形式
二、打包实操
三、Scala 包的叠加使用
四、Scala 包作用域原则
本章节介绍 Scala 包的注意事项和使用细节。
一、scala 打包的形式
scala 进行 package 打包时,有三种形式:
1、代码说明:传统方式。
package com.atguigu.scala
class Person{
val name="Nick"
def play(message:String):Unit={printh(this name+""+message)
}
}
2、代码说明:和传统写法等价,与上面一样。
package com.atguigu
package scala
class Person{
val name="Nick"
def play(message:String):Unit={printh(this name+""+message)
}
}
3、代码说明:此打包方式使用的最多,重点来讲解。
package com. atguigu{
package scala{
class Person{
def play(message:String):Unit={printh(this name+""+message)
}
}
二、打包实操
重点来看第三种打包方式,打开 Scala 新建一个文件 packagedemo:
package com.atguigu.chapter07.scalapackage
object packagedemo {
}
当然从上节课中知道Scala中包名和源码所在的系统文件目录结构可以不一致,所以 package com.atguigu.chapter07.scalapackage
可以去掉,直接写:
package com. atguigu{
package scala{
class Person{
val name="Nick"
def play(message:String):Unit={
println(this name+”“+message)
}
}
}
}
package com.atguigu 是包名而其余是此包所编写的内容,可以是另外的子包,也可以是类等等。也就是package com. atguigu{} 表示创建了包 com. atguigu,在{ }中可继续写其它的子包如 scala(com.atguigu.scala),还可以写类,特质 trait,写 object 等等。
这也意味着在一个文件里面可以创建多个包,并且在各个包中创建各自的类,说明 scala支 持在一个文件中可以创建多个包,以及对多个包创建类、trait、object。这些是 java 无法做到的,java 无法在一个文件中可以创建多个包,需要用到其他包就要创建另一个文件,这就体现了 scala 的灵活。
示例:
package com.atguigu{
//包 com.atguigu
package scala{
//包com.atguigu.scala
class Person{
//表示在 com.atguigu.scala下创建类 person
val name="Nick"
def play(message:String):Unit={
println(this name+”“+message)
}
}
object
Test
100
{
//表示在 com.atguigu.scala创建 object Test
def main(args: Array[string]): unit
=
{
printin(“ok”)
}
}
}
}
此时在 com.atguigu.scala包中已创建了三个类(Person、Test100、Test100$),运行后就会把文件放到当com.atguigu.scala 中,打开目录就可看到,如图:
三、Scala 包的叠加使用
Scala 包也可以像嵌套类那样嵌套使用(包中有包),这个在前面的第三种打包方式已经讲过了,在使用第三种方式时的好处是:程序员可以在同一个文件中,将类(class/object)、trait 创建在不同的包中,这样就非常灵活,打开刚才创建的 packagedemo:
package com.atguigu{
//包com.atguigu
class
U
ser
{
//在com.atguigu包下创建了 User类
}
package scala{
//包com.atguigu.scala
class Person{
//表示在 com.atguigu.scala下创建类 person
val name="Nick"
def play(message:String):Unit={
println(this name+”“+message)
}
}
object
Test
100
{
//表示在com.atguigu.scala创建 object Test
def main(args: Array[string]): unit
=
{
printin(“ok”)
}
}
}
}
可以看到在 com.atguigu 包下创建了 User 类,运行后可看到 com.atguigu下多了 class 文件 User,如图:
同时嵌套使用(包中有包)又怎么实现,如下:
package com.atguigu{
//包 com.atguigu
class
U
ser
{
//在 com.atguigu 包下创建了 User类
}
package
scalal2{
//创建包 com.atguigu. scalal2
class
U
ser
{
/
/在com.atguigu. scalal2 下创建类 User
}
}
package scala{
//包com.atguigu.scala
class Person{
//表示在 com.atguigu.scala下创建类 person
val name="Nick"
def play(message:String):Unit={
println(this name+”“+message)
}
}
object
Test
100
{
//表示在 com.atguigu.scala创建 object Test
def main(args: Array[string]): unit
=
{
printin(“ok”)
}
}
}
}
可看到在 com.atguigu 下创建包 com.atguigu.scalal2,同时又在此包中创建了 Use r类,此时并未报错,因为此时新建的 User 在 com.atguigu.scalal2包下,并未在 com.atguigu 包,运行后会生成 scalal2文件夹,其下有User,如下图:
scalal2文件夹下的 class 文件 User:
当然此时还可以继续加包来实现各种操作,体现出 Scala 的灵活性。
四、Scala 包作用域原则
在同一个文件内可以创建多级包,这就体现出问题在包中相互访问类的问题这又有了作用域原则:
作用域原则:可以直接向上访问。即:Scala 中子包可直接访问父包中的内容,大括号{}体现作用域(提示:Java中子包使用父包的类,需要 import,在 scala 中不需要)。在子爸和父包类重名时,默认采用就近原则,如果希望指定使用某个类,则带上包名即可。如下:
package com.atguigu{
//包com.atguigu
class
U
ser
{
//在 com.atguigu包下创建了 User类
}
package
scalal2{
//创建包 com.atguigu. scalal2
class
U
ser
{
//在 com.atguigu. scalal2下创建类 User
}
}
package scala{
//包com.atguigu.scala
class Person{
//表示在 com.atguigu.scala下创建类 person
val name="Nick"
def play(message:String):Unit={
println(this name+”“+message)
}
}
object
Test
100
{
//表示在com.atguigu.scala创建 object Test
def main(args: Array[string]): unit
=
{
printin(“ok”)
//我们可以直接使用父包的内容
val user=new User
//这里使用的就是父包的 User
printin(“user=”+user)
}
}
}
}
此时看到 scala 是可以引用父包的 User 的如图
如果有同名的的类,则采取就近原则来使用内容(比如包),所以当 scala 有 User 时依据就近原则就会使用自己的User:
package com.atguigu{
//包 com.atguigu
class
U
ser
{
//在 com.atguigu包下创建了 User类
}
package
scalal2{
//创建包 com.atguigu. scalal2
class
U
ser
{
//在 com.atguigu. scalal2下创建类 User
}
}
package scala{
//包com.atguigu.scala
class Person{
//表示在 com.atguigu.scala下创建类 person
val name="Nick"
def play(message:String):Unit={
println(this name+”“+message)
}
}
class
U
ser{
}
object
Test
100
{
//表示在com.atguigu.scala创建 object Test
def main(args: Array[string]): unit
=
{
printin(“ok”)
//我们可以直接使用父包的内容
val user=new User
printin(“user
=”+user)
}
}
}
}
运行后此时就使用的是自己的 User,如下图:
当一定要使用父包的内容,则需要指定路径即可,如下:
package com.atguigu{
//包 com.atguigu
class
U
ser
{
//在 com.atguigu包下创建了 User 类
}
package
scalal2{
//创建包 com.atguigu. scalal2
class
U
ser
{
//在 com.atguigu. scalal2下创建类 User
}
}
package scala{
//包 com.atguigu.scala
class Person{
//表示在 com.atguigu.scala下创建类 person
val name="Nick"
def play(message:String):Unit={
println(this name+”“+message)
}
}
class
U
ser{
}
object
Test
100
{
//表示在 com.atguigu.scala创建 object Test
def main(args: Array[string]): unit
=
{
printin(“ok”)
//我们可以直接使用父包的内容
val user=new User
printin(“user=”+user)
val
user2=new
com
.atguigu.User()
printin(“user
2
”+user)
}
}
}
此时运行就分开使用User了,如下图: