【scala专栏_持续更新】19_scala包+样例类+样例对象

【大纲】
在这里插入图片描述

【正文】

1.包package

1.1.【结论】概念

0.包就是文件夹,用关键字package修饰,它可以区分重名类,相似功能的代码可以放一个包中,便于管理维护

1.编写源码时,scala的包名和源码所在的目录结构可以不一致,编译后,字节码文件会自动和包名路径一致。不过建议源码时最好保持一致
    
2.包名命名规范:
    包名由 数字 大小写英文字母 _ $ 组成
    多级包之间用.分隔
    层级不限 一般2或3层
    一般用公司域名反写命名 com.wsy.utils

1.2.语法

【结论】方式一 合并版 推荐

package xx.yy.zz
    类/特质...

【结论】方式二 分解版

package xx.yy
package zz
    类/特质...

【结论】方式三 串联式包语句

package xx.yy{
    package zz{
        类/特质...
    }
}

1.3.【结论】作用域

0.子包可访问父包内容

1.上层访问下层内容时,需要导包import,或写全包名

2.如上下层有相同的类,则就近原则,想使用远的类,需用上层路径.类名

3.导包语法 后边会讲

示例

package com.wsy {
  
  /**
    * @author: WSY
    * @description: 包 demo
    * @creationDate: 2021/10/25 21:46
    * @modifyDate: 2021/10/25 21:46
    * @version: V1.0
    */

  class Person {}

  class Teacher {}

  package scala{
    class Person{}
    class Student1{}
    object demo{
      def main(args: Array[String]): Unit = {
        println(2)
        // 子包可以直接访问父包中的内容
        new Teacher
        // 子父包有同名类时, 采用就近原则来访问
        new Person
        // 子父包有同名类, 且想访问父包类时, 写全路径即可
        new com.wsy.Person
      }
    }
  }

  object Package {
    def main(args: Array[String]): Unit = {
      println("1")
      // 方式一: 导包, 导包语句可以出现在Scala代码中的任意位置, 不一定是行首
      import com.wsy.scala.Student1
      new Student1
      // 方式二: 全包名
      new com.wsy.scala.Student1
      // 因为当前包就是com.itheima, 所以上述代码可以简写成如下格式
      new scala.Student1
    }
  }
}

1.4.【结论】包对象

0.由于JVM的限制,scala的包中,不能直接定义变量或方法,为了解决此问题,引入了包对象

1.定义包对象语法
    package 父包A{
        package 子包B{
            
        }
        // 子包B的包对象
        package object 子包B{
            
        }
    }
    
# 注意:
    0.包对象和包都要定义到父包中,这样才能使二者平级
    1.包对象和包名必须一致
    2.包对象一般用于对包的功能进行补充与增强

2.作用:
    包对象的特性,主要是scala2.8为了兼容scala2.7.7旧版本而增加的

示例

package com.wsy{ // 父包

  /**
    * @author: WSY
    * @description: 包对象 demo
    * @creationDate: 2021/10/25 22:19
    * @modifyDate: 2021/10/25 22:19
    * @version: V1.0
    */
  package scala{ // 子包
    object PackageObject {
      def main(args: Array[String]): Unit = {
        // 访问当前包对象中的内容
        println(scala.name) // 效果:tom
        hello() // 效果:hello
      }
    }
  }
  package object scala{ // scala包的包对象 和scala包是平级关系
    // 包对象中可定义成员
    val name ="tom"
    def hello() = println("hello")
  }
}

1.5.【结论】包的可见性

访问权限修饰符private表示本类可用,private[com]来修饰成员,表示com包下所有类可用

示例

package com.wsy{ // 父包

/**
  * @author: WSY
  * @description: 包的可见性 demo
  * @creationDate: 2021/10/25 22:33 
  * @modifyDate: 2021/10/25 22:33 
  * @version: V1.0
  */
  class Employee{
    private[wsy] val name = "tom"
    val age = 16
    private[com] def hello() = println("hello")
    private def say() = println("say")
}

  package scala{ // 子包
    object PrivatePackage {
      def main(args: Array[String]): Unit = {
        val employee = new Employee
        println(employee.name) // 效果:tom
        println(employee.age) // 效果:16
        employee.hello() // 效果:hello
//        employee.say() // 效果:报错 无访问权限
      }
    }
  }
}

1.6.【结论】包的引入

0.scala的导包语句不一定非要在行首,可以写到任何需要的地方,可缩小导包的作用范围,提高效率

1.scala默认引入的java.lang包、scala包部分内容、Predef包部分内容

2.导包语法
    import 爷爷包.父包.子包.类名

3.导入某个包中所有内容:
    import xx.yy._ # 下划线代表所有

4.仅导入某个包中的几个类或特质--包选取器
    import xx.yy.zz.{类A, 特质B}

5.导入某个包下除了指定类的其他类
    import java.util.{HashSet => _, HashMap => _, _}
    
6.为避免混淆,导入类时可重命名类名
    import xx.yy.{原始类名A => 新类名AA, 原始类名B => 新类名BB}

示例

object ImportPackage {

  def test01() = {
    // 缩小import包的作用范围, 从而提高效率
    import java.util.HashSet
    val hs = new HashSet

    // 导入包下的所有
    import java.util._
    val hm = new HashMap
    val list = new ArrayList
  }

  def test02() = {
    // 导入包下指定的类
    import java.util.{ArrayList, HashSet}
    val hs = new HashSet
    val list = new ArrayList
  }

  def test03() ={
    import scala.collection.mutable.HashSet
    val hs = new HashSet()
    // 导入类后重命名类
    import java.util.{HashSet => JavaHashSet}
    val jhs = new JavaHashSet
  }

  def test04() = {
    // 导入包下除了指定类的其他类
    import java.util.{HashSet => _, Hashtable => _, _}
    val hm = new HashMap
//    val hs = new HashSet // 效果:代码会报错
  }

  def main(args: Array[String]): Unit = {
    test01
    test02()
    test03()
    test04()
  }
}
// 效果:都不报错

2.样例类

2.1.【结论】作用

scala中的样例类,是一种特殊类,编译器会自动帮样例类生成一些常用方法,样例类常用于保存数据,类似于java的POJO

2.2.【结论】语法

case class 样例类名(val/var 成员变量名: 数据类型 = 默认值, val/var 成员变量名: 数据类型 = 默认值){
    
}
    
# 注意:
    0.主构造参数列表中,可以不写val/var,默认是val
    1.默认值可以不给

示例

object CaseClass {
  case class Person(name:String = "张三", var age:Int = 23){}

  def main(args: Array[String]): Unit = {
    val p = new Person()
    p.age = 25
//    p.name = "tom" // 直接报错 默认val不能修改
  }
}

2.3.【结论】样例类中的默认实现

编译器会自动给样例类默认实现如下内容:

    apply():
        创建对象免new
        
    toString():
        println(样例类对象名),打印对象带各个属性值
        
    equals():
         p1 == p2 比较的是两个样例类对象的各个属性是否相等??
         
    hashCode():
        获取对象的哈希值,同一对象的哈希值一定相同,不同对象的哈希值一般不同
        
    copy():
        可快速创建一个属性值想用的对象,还可使用带名参数给指定的成员变量赋值
        val p1 = new Person("张三", 23)
        val p2 = p1.copy(age = 24)
        println(p1)		// 效果: 张三, 23
        println(p2)		// 效果: 张三, 24
        
    unapply():
        用作提取器,后边会讲
        
    自动继承了Serializable特质
        用作序列化和反序列化,后边会讲

示例

object CaseClass {
  case class Person(var name:String, var age:Int){}

  def main(args: Array[String]): Unit = {
    // 样例类默认实现了apply方法 免new
    val p1 = Person("张三", 23)

    // 样例类重写了toString() 打印直接输出属性值
    println(p1) // 效果:Person(张三,23)

    // 样例类重写了toString() 可以获取到hash值
    println(p1.hashCode())

    // 样例类默认实现了copy方法
    val p2 = p1.copy(age = 30)
    println(p1.hashCode() == p2.hashCode()) // 效果:false

    val p3 = p2.copy()
    println(p2.hashCode() == p3.hashCode()) // 效果:true
  }
}

3.样例对象

3.1.【结论】概念

单例样例类,也叫样例对象

3.2.【结论】语法

case object 单例样例类名
    
# 注意:
    0.样例对象没有主构造器

3.3.【结论】作用

0.当作枚举值使用
    trait Sex
    case object Male extends Sex
    case object Female extends Sex
    
1.作为没有任何参数的消息传递 
    后边会讲 在Akka并发编程处

示例

# 样例对象作为枚举值
object CaseObject {
  trait Sex
  case object Male extends Sex
  case object Female extends Sex

  case class Person(name:String, sex:Sex){}

  def main(args: Array[String]): Unit = {
    val tom = Person("tom", Male)
    // Male如果用case修饰 这里打印出来的是Person(tom,Male)
    // Male如果不用case修饰 这里打印出来的是Person(tom,com.wsy.CaseObject$Male$@56cbfb61)
    println(tom)
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cheese海盐芝士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值