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)
}
}