1 属性
1.1 构造器参数
Scala 类的主构造器函数是可以添加参数的。如果参数未用任何修饰符修饰,那么这个参数是局部变量。
class Scala05_Field(name:String = "zhang3",age:Int){
//此处的 name 未加任何修饰,是局部变量,无法通过对象进行访问
}
object Scala05_Field {
def main(args: Array[String]): Unit = {
val fiObj = new Scala05_Field(age = 10)
}
}
如果参数使用 val 关键字声明,那么 Scala 会将参数作为类的只读属性(不能修改)使用.
class Scala05_Field(val name:String = "zhang3",age:Int){
}
object Scala05_Field {
def main(args: Array[String]): Unit = {
val fiObj = new Scala05_Field(age = 10)
println(fiObj.name)
//这里调用对象的 name 属性,其实并不是属性,而是方法,因为方法无参数,所以省略了小括号,感觉和调用属性一样,这体现了 Scala 语言访问一致性
}
}
运行结果:
zhang3
Process finished with exit code 0
- 如果参数使用 var 关键字声明,那么那么 Scala 会将参数作为类的成员属性使用,并会提供属性对应的 setter/getter 方法
class Scala05_Field(val name:String = "zhang3",var age:Int){
@BeanPropertry
}
object Scala05_Field {
def main(args: Array[String]): Unit = {
val fiObj = new Scala05_Field(age = 10)
println(fiObj.name)
fiObj.age = 20; // setter方法
println(fiObj.age) //getter方法
}
}
1.2 Bean 属性
- JavaBeans 规范定义了 Java 的属性是像getXXX()和 setXXX()的方法。许多 Java工具(框架)都依赖这个命名习惯。为了 Java 的互操作性。将 Scala 字段加@BeanProperty时,这样会自动生成 setter/getter 方法。
package com.nefu.scala.chaptor03
import scala.beans._
/** *******************
*
* @auther Dr.Li
* @create 2020-01-06 18:38
* ********************/
/*
如果需要使用Java类型的方法,那么还需要在属性之前用BeanProperty修饰
*/
class Scala05_Field(val name:String = "zhang3",@BeanProperty var age:Int){
}
object Scala05_Field {
def main(args: Array[String]): Unit = {
val fiObj = new Scala05_Field(age = 10)
println(fiObj.name)
fiObj.age = 20; // setter方法
println(fiObj.age) //getter方法
println(fiObj.getAge) //Java的get方法。
}
}
2 包
2.1 包的作用域
在 Java 和 Scala 中管理项目可以使用包结构, C 和 C#使用命名空间。
对于 package,有如下几种形式:
2.1.1 形式体现
package com.nefu.scala.chaptor03
/** *******************
*
* @auther Dr.Li
* @create 2020-01-06 19:05
* ********************/
class Scala06_Package {
}
等价于
package com.nefu.scala
package chaptor03
/** *******************
*
* @auther Dr.Li
* @create 2020-01-06 19:05
* ********************/
class Scala06_Package {
}
等价于
package com.nefu.scala {
package chaptor03{
class Scala06_Package {
}
}
}
注: 位于文件顶部不带花括号的包声明在对当前整个文件内的包声明有效。
通过以上形式,总结如下:
1、 包也可以像嵌套类那样嵌套使用(包中有包) 。
2、 作用域原则:可以直接向上访问。即,子包中直接访问父包中的内容。 (即: 作用域)
3、 源文件的目录和包之间并没有强制的关联关系
4、 可以在同一个.scala 文件中,声明多个并列的 package
5、 包名可以相对也可以绝对,比如,访问 BeanProperty 的绝对路径是:
root. scala.beans.BeanProperty
package com.nefu.scala {
import com.nefu.scala.chaptor03.Scala06_Package
package chaptor03{
class Scala06_Package {
}
}
object PackageTest{
def main(args: Array[String]): Unit = {
//使用这个对象需要导包;作用域问题
//import com.nefu.scala.chaptor03.Scala06_Package
val paObj = new Scala06_Package
}
}
}
package com.nefu.scala {
package chaptor03{
class Scala06_Package {
}
}
object PackageTest{
def main(args: Array[String]): Unit = {
// 也可以在声明之前加上包的名
val paObj = new chaptor03.Scala06_Package
}
}
}
package com.nefu.scala {
package chaptor03{
class Scala06_Package {
}
}
object PackageTest{
def main(args: Array[String]): Unit = {
// 也可以在任何位置导包
import chaptor03._
val paObj = new Scala06_Package
}
}
}
package com.nefu.scala {
package chaptor03{
class Scala06_Package {
}
}
object PackageTest{
def main(args: Array[String]): Unit = {
// 也可以在任何位置导包
import chaptor03._
val paObj = new Scala06_Package
}
}
}
package com.nefu.test{
//可以多个包并列
//引用绝对路径
import _root_. scala.beans.BeanProperty
class Test111(@BeanProperty val name:String = "abc"){
}
}
使用方便;
2.2 包对象
包可以包含类、对象和特质 trait, 但不能包含函数或变量的定义。很不幸,这是 Java虚拟机的局限。 为了弥补这一点不足, scala 提供了包对象的概念来解决这个问题
package object charter03{
//每个包都可以有一个包对象。你需要在父包中定义它,且名
//称与子包一样。
val name = "zhang3"
def testFunction(){
}
}
object PackageTest{
def main(args: Array[String]): Unit = {
// 也可以在任何位置导包
import chaptor03._
val paObj = new Scala06_Package
}
}
package chaptor03{
class Scala06_Package {
}
}
package object chaptor03{
//每个包都可以有一个包对象。你需要在父包中定义它,且名
//称与子包一样。
val name = "zhang3"
def testFunction(){
println("包的函数")
}
}
object PackageTest{
def main(args: Array[String]): Unit = {
import com.nefu.scala.chaptor03._
testFunction() //调用包的方法
}
}
2.3 包可见性
- 在 Java 中, 访问权限分为种: public, private,protected, 缺省的。在 Scala 中,你可以通过类似的修饰符达到同样的效果。 但是使用上有区别。
- 当访问权限缺省时, scala 默认为 public 访问权限。
- 私有权限
- 受保护权限
- 包访问权限
package com.nefu.scala.chaptor04
/** *******************
*
* @auther Dr.Li
* @create 2020-03-06 10:13
* ********************/
/*
包的可见性:(权限修饰符)
[default]<==>public 公开的(任意位置)
private 私有的
protected 受保护的(只能在父子类关系中可见)
private[包路径] 复合的(本类范围和指定包路径可见)
protected[包路径] 复合的(父子类范围和指定包路径中可见)
*/
object Scala01_Package {
def main(args: Array[String]): Unit = {
val sptest = new Scala01_PaTest1()
println(sptest.name)
println(sptest.age)
println(sptest.sex)
}
}
class Scala01_PaTest1{
var name = "zhang3"
private[subpac] var age = 40
protected[chaptor04] var sex = false
}
class Scala01_SubTest2{
def test():Unit = {
val sptest = new Scala01_PaTest1()
println(sptest.name)
println(sptest.age)
println(sptest.sex)
}
}
package subpac{
class Scala01_SubTest1 extends Scala01_PaTest1{
def test():Unit={
println(name)
println(age)
println(sex)
}
}
}
2.4 引用
- 因为 Scala 语言源自于 Java,所以 java.lang 包中的类会自动引入到当前环境中,而 Scala中的 scala 包和 Predef 包的类也会自动引入到当前环境中。如果想要把其他包中的类引入到当前环境中,需要使用 import 语言
- 在 Scala 中, import 语句可以出现在任何地方,并不仅限于文件顶部。
import java.util.HashMap
/*
任意位置可以导包
*/
val map = new util.HashMap()
注: import 语句的效果一直延伸到包含该语句的块末尾
/*
Scala中以下三个位置的内容在使用不需要导包;
scala,java.lang,PreDef
*/
val str: Integer = 0;
- 在 Java 中如果想要导入包中所有的类,可以通过通配符星号, Scala 中采用下划线
class User {
import scala.beans._ // 这里采用下划线作为通配符
@BeanProperty var name : String = ""
}
- 如果不想要某个包中全部的类,而是其中的几个类,可以采用选取器(大括号)
import java.util.{HashMap,ArrayList}
val map2 = new HashMap()
2.5 重命名和隐藏
- 如果引入的多个包中含有相同的类,那么可以将不需要的类进行重命名进行区分。
重命名:
import java.util.{HashMap=>JavaHashMap,ArrayList}
import scala.collection.immutable.{HashMap=>ScalaHashMap}
val map2 = new JavaHashMap()
- 这样一来, JavaHashMap 就是 java.utiI.HashMap,而 HashMap 则对应scala.collection.mutable.HashMap。
如果某个冲突的类根本就不会用到,那么这个类可以直接隐藏掉。
import java.util.{HashMap=>_ ,_}
import scala.collection.mutable._
var map1 = new HashMap()