欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

快学Scala(七)--包和引入简单示例

程序员文章站 2022-03-04 14:05:09
...
package org.qianfeng.scala.chapter07.packageandimport

/**
  * scala包
  */
/**
  * scala中的包和java中的包目的相同:管理大型程序中的名称。
  * 例如:我们之前就学习过的scala.collection.immutable.Map
  * 和scala.collection.mutable.Map就是两个不同的Map
  * 示例如下:
  */
//在包edu.beicai中添加类a
package edu {
  package beicai {

    class a {

    }

  }

}

//经过上述定义,我们就可以在任何位置以edu.beicai.a的形式来访问a类了
/**
  * 上述包定义代码不只是可以写在当前源文件中,其他源文件中也可以写。
  * 即:在不同源文件中包相同也是可是的。
  * 例如我们在另一个源文件中这样定义
  */
//这里为了演示方便就放在一起了,实际上应该在另一个源文件中。即a类和b类都在同一个包中
//在包edu.beicai中添加类a
package edu {
  package beicai {

    class b {

    }

  }

}

/**
  * 同样的,我们可以在一个源文件中对多个包添加内容。
  * 示例如下:
  */
//在包edu.beicai1中添加类b
package edu {
  package beicai1 {

    class b {

    }

  }

}

/*-----------------包的作用域规则---------------------*/
/**
  * scala中包同其他作用域一样支持嵌套,你可以直接访问上层包中的内容。
  * 示例如下:
  */
//com包内含有两个父子级别的包beicai1和beicai2
package com {
  package beicai1 {

    object Utils {
      def methoda() = {}
    }
    package beicai2 {

      class test {
        //在这里调用父包中的内容
        Utils.methoda()
      }

    }

  }

}

//假如自定义包和其他包中的内容有冲突将无法通过编译
package edu {
  package collection {

    object tt {
      //在这里访问collection将无法通过编译
      /**
        * 报错信息如下:
        * object Mutable is not a member of package edu.beicai.scala.chapter7.packgeandimport.edu.collection
        */
      //      val myval = new collection.Mutable.ArrayBuffer(10)
    }

  }

}

/*--------------------串联包--------------------*/
package edu.beicai.class1506b {
  //包edu和edu.beicai中的其他成员在这里不可见
  /*
   * 因为scala中包名是相对的(可以不用像java那样使用绝对路径),
   * 所以有时候可能会造成不知道导入哪一个包中的类,通过串联包的形式可以
   * 直接指定到可访问的域,避免一个类同时出现在多个包中。
   */
}

/*--------------------文件顶部标记法--------------------*/
/*
 * 就是我们平常最常见的形式,在本源文件的头部就定义了本源文件所属的包。 
 */

/*--------------------包对象--------------------*/
/*
 * 在java中,包内部可以包含类和接口,但是不能包含函数或变量的定义,这是jvm的局限。
 * 有时候,把工具函数或常量添加到包而不是某个Utils对象,是更合理的做法。scala包对象的目的就是解决这个局限。
 * 每个包都可以有一个包对象,你需要在父包中定义,且要求名字与包名相同。
 * 示例如下:
 */
package test {

  //包对象
  package object pa {
    //定义包内部的类或对象所需使用的常量
    val one = "壹"
    //还可以定义一些Util函数
  }

  //包
  package pa {

    //包中的单例对象
    object t {
      //使用包对象中的变量
      val yi = one
      //因为本单例对象所在的包跟包对象同处一个包(test)内,所以上述方式可行,
      //如果其他地方也想使用one这个变量,需要使用下面的方式:
      val yi1 = test.pa.one
    }

  }

}

/*
 * 在java层面,包对象的本质是带有静态方法和静态字段的JVM类。
 * 推荐将包对象代码放在其所属的位置的源文件中(因为scala太灵活,放哪定义都可以),这样方便查找。 
 */

/*--------------------包可见性--------------------*/
/*
 * 在java中没有显示声明权限的类成员在包含该类的包中可见。
 * scala中可以添加如下形式的修饰符来达到同样的效果。
 * 示例如下:
 */
package myp {
  package sunmyp {

    class Person {
      //定义functiona函数只对sunmyp包(同包)中的其他成员可见
      private[sunmyp] def functiona = {}

      //定义functionb函数只对myp包(父包)中的其他成员可见
      private[myp] def functionb = {}
    }

  }

}

/*--------------------包引入--------------------*/
/*
 * 引入某个包以后,你想使用包内的内容就不必再写包名了,这是包引入的唯一目的。
 * 我们一开始接触导包的时候说到过导入某个包下的所有内容的方法:
 * 示例如下:
 */
//引入awt包中的所有内容
import java.awt._
//与java的唯一不同在于 _ 替换了 *

//引入Color类中的所有内容
import java.awt.Color._

/*
 * scala在任何地方都可以声明引入语句,这是一个非常好的特性,
 * 可以大幅减少可能存在的命名冲突
 */

//引入包中的部分成员
import java.awt.{Color, Font}
//只引入awt包中的Color和Font类,java中需要写两行来实现同样的效果

//在引入包时对引入的成员同时进行重命名
import java.util.{HashMap => JavaHashMap}
import scala.collection.mutable._
//通过上述两个引入之后,后续的代码中HashMap就指得是scala.collection.mutable.HashMap
//想直接使用java的HashMap只需直接用JavaHashMap即可

//导入包内成员时指定   不导入   某个包成员
//引入java.util包中除了HashMap之外的其他包成员
import java.util.{HashMap => _} //"HashMap =>_"含义是将HashMap在导入时排除掉
/*
 * 就像java程序总是隐式默认引入java.lang包
 * 
 * scala的默认包引入顺序如下:
 * import java.lang._
 * import java.scala._
 * import java.Predef._//这个包中也有大量有用的函数
 * 
 * 与java有所不同的是,scala包中自己丰富过的类会将java中的覆盖掉而不引发冲突。
 * 例如scala.StringBuilder 会覆盖  java.lang.StringBuilder
 */

//因为scala包已经被默认引入了,所以往后我们可以使用如下的形式导入包
import collection.mutable.HashMap
//其与下述的引入方式只是相对地址和绝对地址的区别
import scala.collection.mutable.HashMap

 

相关标签: Scala