8.2 包

Scala 中包的声明, 命名规则和 Java 完全一样, 在此不再赘述.

只学习下与 Java 不同的地方


8.2.1 包语句

Java 的中的包的声明一般是通过 package x.y.z 来声明.

Scala 不仅仅支持 Java 的这种声明方式, 还支持另外一种更加灵活的方式: 包语句

package com{
  package atguigu{
    class Person{  // com.atguigu.Person

    }
  }
}

package com{
  package atguigu{
    package xx{
      class Person{  // com.atguigu.xx.Person

      }
    }
  }
}

说明:

  • 一个文件中的多个类可以使用不同的包
  • 包的结构将来也和文件夹结构没有必然联系了
  • 如果一个文件的中的所有的类都属于同一个包, 最好使用 Java 提供的顶部标记法, 而实际情况也确实是这样是最普遍的做法.

8.2.2 包对象

在 Java 中, 我们的一些工具函数或者常量需要专门添加到一个所谓的类中. 这种做法主要是 JVM 的限制, 但其实并不是很好的选择.

如果能把这些东西添加到包中是更好的一种选择.

Scala 提供的包对象解决了这个问题

每个包都有一个包对象, 我们需要在类的父包中进行定义, 并且和父包的名字保持一致!
package com.atguigu.day04

package abc {

  object Person {
    def main(args: Array[String]): Unit = {
      val p1 = new Person()
      p1.say()
    }
  }

}

package object abc {
  var A: Int = 3

  def foo() = {
    println("包对象中定义的函数...")
  }
}
package abc {

  class Person {
    def say() = {
      // 调用包对象中的属性和方法时, 直接调用即可, 不需要前缀
      println(A)
      foo()
    }
  }
}

说明:

  • 在幕后, 包对象被编译成类, 名字就叫package.class, 放在相应的包下.

  • 本例中放在包com.atguigu.day04.abc


8.2.3 包的可见性

在 Java 中,访问权限分为: publicprivateprotected默认。在Scala 中,你可以通过类似的修饰符达到同样的效果。但是使用上有区别。

  1. 当方法访问权限为默认时,默认为public访问权限

  2. 在 Scala 中没有public关键字,即不能用public显式的修饰属性和方法。

  3. private为私有权限,只在类的内部和伴生对象中可用

    关于伴生对象和伴生类的概念, 后面再细说

    package com.atguigu.day04
    /*
    当在一个文件中, object 名和 class 名相同时
    object 叫伴生对象, class 叫伴生类
    */
    object AccessTest {
     def main(args: Array[String]): Unit = {
       val test = new AccessTest
       // 伴生对象内部可以访问伴生类内部的私有属性和方法
       println(test.a)
     }
    }
    
    class AccessTest{
     private var a = 10
    
     def foo(): Unit ={
       println(a)
     }
    }
    
  4. protected为受保护权限,Scala 中受保护权限比 Java 中更严格,只能子类访问,同包无法访问。

  5. 包访问权限 一般是属性私有了, 可以增加包访问权限, 然后包内的其他类也可以访问到了. 这点体现出来了 Scala 包相比 Java 的灵活性.


8.2.4 包的导入

Scala 中导包用的关键字仍然是import

Scala 导入的特点:

1. 在 Scala 中,import 语句可以出现在任何地方,并不仅限于文件顶部.

import语句的作用一直延伸到包含该语句的块末尾

这种语法的好处是:在需要时在引入包,缩小import 包的作用范围,提高效率

2. Scala 使用_来导入一个包下的所有的类(Java 是*)

3. 如果不想要某个包中全部的类, 而是其中的几个类, 可以采用选取器(大括号)

4. 类的重命名

如果引入的多个包中含有相同的类,那么可以将不需要的类进行重命名进行区分,这个就是重命名

package com.atguigu.day04

// Scala 提供的 HashMap
import scala.collection.mutable.HashMap

// 给 Java 的HashMap重命名为JavaHashMap
import java.util.{HashMap => JavaHashMap}


object PackDemo3 {
  def main(args: Array[String]): Unit = {
    // 使用重命名后的JavaHashMap
    val map1 = new JavaHashMap[String, String]()
    val map2 = new HashMap[String, String]()

  }
}

5. 如果某个冲突的类根本就不会用到,那么这个类可以直接隐藏掉

package com.atguigu.day04
// 隐藏scala.collection.mutable.HashMap
import scala.collection.mutable.{HashMap => _, _}
import java.util._
//import  java.util.{HashMap=>_, _}


object PackDemo3 {
  def main(args: Array[String]): Unit = {
    // 毫无疑问的指向了java.util.HashMap
    val map2 = new HashMap[String, String]()

  }
}

6. 隐式引入

下面 2 个包的所有类都被隐式引入:

import java.lang._
import scala._

和对象:

import scala.Predef._

Predef 对象中包含了类型、隐式转换以及在 Scala 中常用的一些方法。

所以,既然已经默认导入,那么无须任何前缀或者导入,就可以直接使用那些方法和隐式转换。

它们太方便了,以至于你开始相信它们是 Scala 的一部分,实际上它们是 Scala 标准库的一部分。

Predef 对象还提供了一些类型的别名,如 scala.collection.immutable.Setscala.collection.immutable.Map

因此,当使用 Set 或者 Map 的时候,实际使用的是 Predef 中对它们的定义,它们分别指向它们在 scala.collection.immutable 包中的定义。

Copyright © 尚硅谷大数据 2019 all right reserved,powered by Gitbook
该文件最后修订时间: 2019-07-02 08:12:45

results matching ""

    No results matching ""