06_Scala_packages_包
包 实际上就是创建不同的文件夹来保存类文件
- 区分不同的类名
- 管理类
- 控制访问范围
- 可以对类的功能进行扩展
Java:包名和源码所在的系统文件目录结构要一致,并且编译后的字节码文件路径也和包名保持一致
Scala: 包名和源码所在的系统文件目录结构要可以不一致,但是编译后的字节码文件路径和包名会保持一致(由编译器完成)
命名规范: com.公司名.项目名.业务模块名 com.xxxx.oa.model, com.xxx.oa.controller
Scala会自动引入的常用包 (java.lang.* scala, Predef)
1) 使用package打包,例 如上图
2) 包中有包(嵌套),好处是:可以在同一个文件中,将类(class / object)、trait 创建在不同的包中,非常灵活
3)作用域原则:可以直接向上访问。即: Scala中子包中直接访问父包中的内容, 大括号体现作用域。在子包和父包 类重名时,默认采用就近原则,如果希望指定使用某个类,则带上包名即可
4) 父包要访问子包的内容时,需要import对应的类等
5)可以在同一个.scala文件中,声明多个并列的package(建议嵌套的pakage不要超过3层)
6) 包名可以相对也可以绝对,比如,访问BeanProperty的绝对路径是:_root_. scala.beans.BeanProperty ,在一般情况下:我们使用相对路径来引入包,只有当包名冲突时,使用绝对路径来处理
// 生成了 scala包 Person.class TestAlex$.class TestAlex.class user.class
// user.class
// scala_new 包 user.class employee.class
package com.alex { //包 com.alex
class user { // com.alex 下创建 user 类
def hello: Unit = {
//父包要访问子包的内容时,需要import对应的类
import com.alex.scala_new.employee // //想使用 com.alex.scala_update包下的 employee, 或者
val employee = new employee()
}
}
package scala_new {
class user { //包 com.alex.scala_new 下创建user类
}
class employee{}
}
package scala { //包 com.alex.scala
class user{
}
class Person {
val name = "Alex"
def play(message: String): Unit = {
println(this.name + " " + message)
}
}
object TestAlex { ////包 com.alex.scala 下 创建 object TestAlex
def main(args: Array[String]): Unit = {
println("ok")
//可以直接使用父包的内容
//1.如果有同名的类,则采用就近原则来使用内容(比如包)
//2.如果就是要使用父包的类,则指定路径即可
val user = new user() //user = OOP.packages.com.alex.scala.user@11531931
println("user = " + user)
val user_new = new com.alex.scala_new.user()
println("user_new = " + user_new) //user_new = OOP.packages.com.alex.scala_new.user@5e025e70
val employee = new com.alex.scala_new.employee() //OOP.packages.com.alex.scala_new.employee@1fbc7afb
println(employee)
}
}
}
}
class Mr(var name: String) {
//第一种形式 [使用相对路径引入包]
@BeanProperty var age: Int = _
//第二种形式, 和第一种一样,都是相对路径引入
@scala.beans.BeanProperty var age2: Int = _
//第三种形式, 是绝对路径引入,可以解决包名冲突 从根路径开始,很少使用
@_root_.scala.beans.BeanProperty var age3: Int = _
}
包对象
包可以包含类、对象和特质trait,但不能包含函数/方法或变量的定义。这是JVM的局限。而scala提供了包对象来解决
- 创建包对象后,在该包下生成 public final class package 和 public final class package$
- 通过 package$ 的一个静态实例完成对包对象中的属性和方法的调用
- 每个包都可以仅有一个包对象 在父包中定义它 (包对象和包是平级的)
-
包对象名称需要和包名一致,一般用来对包的功能补充
package com.alex2 { //包 com.alex2
package scala_new {
class user { //包 com.alex2.scala_new 下创建user类
}
class employee{
}
object test100{
def main(args: Array[String]): Unit = {
println( "name: " + name)
hello()
}
}
}
//说明
//1. 在包中直接写方法,或者定义变量,就错误==>使用包对象的技术来解决
//2. package object scala_new 表示创建一个包对象 scala_new, 他是 com.alex2.scala_new这个包对应的包对象
//3. 每一个包都可以有一个包对象
//4. 包对象的名字需要和子包一样 package object scala_new & package scala_new
//5. 在包对象中可以定义变量,方法
//6. 在包对象中定义的变量和方法,就可以在对应的包中使用
//7. 在底层这个包对象会生成两个类 package.class 和 package$.class (name & hello 进行了二次封装)
package object scala_new{ // 在父包 com.alex2 中定义
var name: String = "alex"
def hello():Unit = {print(name )}
}
}
Java 四种访问修饰符范围 (修饰符可以 修饰类中的属性,成员方法以及类 【默认/public才能修饰类, protected 子类可以不在同一个包】)
访问级别 | 修饰符 | 同类 | 同包 | 子类 | 不同包 | |
1 | 公开 | public | √ | √ | √ | √ |
2 | 保护 | protected | √ | √ | √ | × |
3 | 默认 | default | √ | √ | × | × |
4 | 私有 | private | √ | × | × | × |
修饰符 | Scala 可见性 |
默认属性 | 当属性访问权限为默认时,从底层是private的,但提供了xxx_$eq()[类似setter]/xxx()[类似getter] 方法,因此任何地方都可以访问) |
默认方法
|
当方法访问权限为默认时,默认为public访问权限
|
private
|
private为私有权限,只在类的内部和伴生对象中可用
|
protected
|
protected为受保护权限,更严格,只能子类访问,同包无法访问
|
无public | 在scala中没有public关键字,即不能用public显式的修饰属性和方法 |
包权限 | 包访问权限(表示属性有了限制。同时包也有了限制) 相当于给访问权限扩大范围 |
object Vist {
def main(args: Array[String]): Unit = {
val person = new Person
person.name // 可以访问 private [packages]
person.name_new //可以访问 protected[packages]
val aa = new AA
// aa.sal // 报错 private 无法访问,只能在本类内部/伴生对象 使用,要使用需要 private[包名]
}
}
// 当一个文件同时出现 class AA object AA , 称object AA 伴生对象, class AA 伴生类, 可以理解为静态 static(Scala理解 static是非对象的)
// 将非静态的部分 放在伴生类中,静态内容放在伴生对象中
class AA {
var name: String = "alex" //底层也是私有的,但是生成了可读可写的方法
private var sal: Double = 9999.9 // 底层私有,但是仅仅生成了可读方法
protected var age = 10
var job : String = "大数据工程师" // 不需要显性使用public,但是底层提供了get set 方法
def showInfo(): Unit = {
//在本类可以使用私有的
println(" name " + name + " sal= " + sal)
}
}
object AA {
def test(a: AA): Unit = {
//这里体现出在伴生对象中,可以访问private a.sal
println("test() name=" + a.name + " sal= " + a.sal)
}
}
class Person {
//这里我们增加一个包访问权限
//下面private[visit] : 1,仍然是private 2. 在vist包(包括子包)下也可以使用name ,相当于扩大访问范围
//下面private[packages] : 1,仍然是private 2. 在packages包(包括子包)下也可以使用name ,相当于扩大访问范围
private [packages] val name = "alex"
protected[packages] val name_new = "bob"
}
Scala 引包 details
import java.util.{ HashMap=>JavaHashMap, List}
import scala.beans._ //_表示将该包的所有内容引入,等价 *
object TestImport {
def main(args: Array[String]): Unit = {
}
}
class User {
import scala.beans.BeanProperty //在需要时才引入,作用域在{}
@BeanProperty var name : String = ""
def test(): Unit = {
//可以使用选择器,选择引入包的内容,这里,我们只引入 HashMap, HashSet
import scala.collection.mutable.{HashMap, HashSet}
var map = new HashMap()
var set = new HashSet()
}
def test2(): Unit = {
//下面的含义是 将 java.util.HashMap 重命名为 JavaHashMap
import java.util.{ HashMap=>JavaHashMap, List}
import scala.collection.mutable._
var map = new HashMap() // 此时的HashMap指向的是scala中的HashMap
var map1 = new JavaHashMap(); // 此时使用的java中hashMap的别名
}
def test3: Unit = {
import java.util.{ HashMap=>_, _} // 含义为 引入java.util包的所有类,但是忽略 HahsMap类. 第一个 _ 代表吧hashmap 隐藏掉,第二个 _ 代表把其它引入
var map = new HashMap() // 此时的HashMap指向的是scala中的HashMap, 而且idea工具,的提示也不会显示java.util的HashMaple
}
}
class Uesr_new {
@BeanProperty var name : String = "" // 不可以直接引用,要么{}中再次引用,要么提到最上面统一引入
}
- 点赞
- 收藏
- 关注作者
评论(0)