scala伴生对象与case class用法

之前用过scala中的伴生对象,隔一段时间不用又有点忘记掉了。特此记录,方便后续查找。

1.伴生对象语法

class MyClass {
	def printname() = {
		println(s"myname is: ${MyClass.name}")
	}
}

object MyClass {
	private val name="xlili"
	private val age=10;
	
	def printStaticMethod() = {
		println("static method don't need instantiate!")
	}
}

在同一个文件中,有如上的代码,代码包含有MyClass类与MyClass对象。如果在同一文件中同时有class xxx与object xxx时,
class xxx被称为object xxx的伴生类
object xxx被称为class xxx的伴生对象
需要注意的是,class xxx与object xxx中的xxx名字要相同。

2.编译结果

编译完成以后,伴生类class xxx编译结果为xxx.class,而伴生对象object xxx编译结果为x$.class

3.伴生对象的作用

大家肯定都会问,为什么需要伴生对象?
伴生对象存在的价值,就是因为scala中没有static关键字,可以解决scala中实现类似Java中的类,在一个类里面既有实例成员变量,又有静态变量。

同时,伴生类与伴生对象中的private属性,还可以相互访问。

	def ttt() = {
		val obj = new MyClass
		obj.printname()
		MyClass.printStaticMethod()
	}

上面的代码运行结果为:

myname is: xlili
static method don't need instantiate!

上面的例子就说明了以上两点:
1.伴生类与伴生对象可以相互访问各自私有属性。
2.伴生对象中的方法可以用类名直接调用,相当于实现了Java中的static方法。

4.case class

case class与普通class的区别主要有
1.case class中的每个参数都以val的形式存在,除非显式声明为var
2.case class自动生成伴生对象,且伴生对象中会自动生成apply方法,因此case class可以直接用类名生成对象而省略new关键字。
3.case class中的伴生对象还会自动生成unapply方法,unapply方法会提取主构造器的参数进行模式匹配。
4.自动产生copy方法,来构建一个与现有值相同的新对象
5.case class中自动产生hashcode,toString,equals等方法

5.sealed关键字

当case class的父类使用关键字sealed修饰的时候,编译器会校验对该超类对象的模式匹配规则中,是否列出了全部可能的子case类。看一个具体实例

sealed abstract class PClass
case class S1(name: String) extends PClass
case class S2(name: String) extends PClass
case class S3(name: String) extends PClass

def t1() = {
	val p: PClass = S2("xxx")
	p match {
		case S1(_) => println("I'm S1!")
		case S2(_) => println("I'm S2!")
	}
}

上面的代码,编译器就会发出警告,因为没有对S3进行模式匹配,所以会出问题。
当然解决的方法,就是加上对S3的模式匹配。

所以,使用 sealed 修饰某个 class 的目的是让 Scala 知道所有 case 的情况,否则会编译报错。
当然我们还可以作弊,使用 @unchecked 告诉编译器可以不用检查也能编译通过。

扫描二维码关注公众号,回复: 15265478 查看本文章

当使用 sealed 来修饰某个 class 时,注意继承该类的其他子类需要跟父类在同一文件中。

猜你喜欢

转载自blog.csdn.net/bitcarmanlee/article/details/128736290