scala Object

yunfenglee 2020-05-30

Object

在scala中被object关键字修饰的类有如下特征:
1、是单例的
2、不需要通过new来创建对象,直接通过类名创建
3、没有有参的主构造器,但是有主构造代码块(不包含在任何方法中的代码,就是object的主构造代码块)
4、通常用于封装一些常量、工具类、枚举和隐式转换函数
5、主构造代码块只会执行一次,因为是单例的

object ObjectDemo {
  println("ObjectDemo 的主构造代码块")
  def sayHello = println("hello world")

  println("ObjectDemo 的主构造代码块2")

}

object ObjectDemo2 {
  def main(args: Array[String]): Unit = {
    val obj1 = ObjectDemo
    val obj2 = ObjectDemo
    println(obj1.hashCode() == obj2.hashCode())

  }
}
运行结果:
ObjectDemo 的主构造代码块
ObjectDemo 的主构造代码块2
true

object.apply方法

package clazz

object ObjectDemo_02 {
  println("hello world")

  def apply() = {
    println("hello")
  }

  def apply(nums: Int*): Array[Int] = {
    val arr = new Array[Int](nums.length)
    for (i <- 0 to nums.length - 1) arr(i) = nums(i)
    arr
  }
}

object ObjectDemo_0201 {
  def main(args: Array[String]): Unit = {
    //创建了一个ObjectDemo_02对象
    val o = ObjectDemo_02
    println("----------------")
    //创建了一个ObjectDemo_02对象,并且调用了无参的apply方法
    val o1 = ObjectDemo_02()
    println("----------------")
    //创建了一个ObjectDemo_02对象,并且调用了有参的apply方法
    val o2 = ObjectDemo_02(1, 2, 2, 3) //ObjectDemo_02(1, 2, 2, 3) 等同于显示调用  ObjectDemo_02.apply(1,2,2,3)
    o2.foreach(println(_))
  }
}
运行结果:
hello world
----------------
hello
----------------
1
2
2
3

伴生类与伴生对象

?* 伴生类和伴生对象一定要在同一个类文件中,并且类名相同
?* 伴生类和伴生对象的特点是可以相互访问被private修饰的字段

//伴生类
class MyArray {
  private var name: String = "小明"
  println(MyArray.name)
}
//伴生对象
object MyArray {
  private var name: String = "小红"
  println(new MyArray().name)

  def apply(nums: Int*): Array[Int] = {
    val arr = new Array[Int](nums.length)
    for (i <- 0 to nums.length - 1) arr(i) = nums(i)
    arr
  }
}

object ObjectDemo_03 {
  def main(args: Array[String]): Unit = {
    //类比数组的创建方式
    var arr = Array(1, 2, 3) //通过伴生对象和有参的apply方法创建对象
    var arr2 = new Array[Int](5) //通过伴生类创建对象

    var arr3 = MyArray(1, 2, 3)
    println("------")
    var arr4 = new MyArray()
  }
}
运行结果:
小红
小明
------
小红

object继承App,App内部有个main方法,object不用main也可执行。

object ObjectDemo_04 extends App {
  println("hello")
}

object枚举

伴生对象继承Enumeration

object MyEnum extends Enumeration {
  //方式1
//  val RED, GREEN, YELLOW = Value
  //方式2
  val RED2 = Value(0, "red2")
  val GREEN2 = Value(1, "green2")
  val YELLOW2 = Value(2, "yellow2")
}

object ObjectDemo_05 {
  def main(args: Array[String]): Unit = {
//    println(MyEnum.GREEN)
    //通过枚举角标获取枚举值
    println(MyEnum(0))
    //通过枚举名称获取枚举值
    println(MyEnum.withName("green2"))
    println("----")
    //获取所有的枚举值
    val vs = MyEnum.values
    for (i <- vs) println(i)
  }
}

外部类与内部类
?* 每个外部类的实例所持有的内部类都是不同的类!!!

class Person {
  //内部类
  class Student

  def getStu: Student = {
    new Student
  }
  val lb = ListBuffer[Student]()
}


object ObjectDemo_06 {
  def main(args: Array[String]): Unit = {

    val p1 = new Person
    val stu1: p1.Student = p1.getStu //类型为:p1.Student
    p1.lb += stu1

    val p2 = new Person
    val stu2: p2.Student = p2.getStu //类型为:p2.Student
    p2.lb += stu2

  }
}

扩大内部类的作用域

package clazz

import scala.collection.mutable.ListBuffer

class Person {
  //内部类
  class Student

  def getStu: Student = {
    new Student
  }

  //通过外部类的类型投影,扩大内部类的影响范围
  //ListBuffer 容器可以放多个外部类的实例所持有的内部类对象了
    val lb = ListBuffer[Person#Student]()

}

object ObjectDemo_06 {
  def main(args: Array[String]): Unit = {

    //扩大内部类的影响范围----1、类型投影----2、内部类放在伴生对象中,实现单例
    val p3 = new Person
    val stu3: p3.Student = p3.getStu //类型为:p1.Student

    val p4 = new Person
    val stu4: p4.Student = p4.getStu //类型为:p2.Student
    
    p3.lb += stu3
    p3.lb += stu4
    println(p3.lb.size) //2

  }
}

case class

样例类:与普通类基本一致,只是可以不使用new来创建对象

case class Student(var name:String,var age:Int) {
  println(s"hello,I am $name, $age years old")
}

object ObjectDemo_07 {
  def main(args: Array[String]): Unit = {
    val s1 = Student("小明",12)
    val s2 = new Student("小王",10)
  }
}

原文链接:https://blog.csdn.net/ym01213/article/details/81105556

相关推荐