Scala樣例類詳細解釋
阿新 • • 發佈:2018-12-25
2.實現了unapply方法,可以通過模式匹配來獲取類屬性,是Scala中抽取器的實現和模式匹配的關鍵方法。
?
構造引數為var的情況:
?
4.還預設幫你實現了toString,equals,copy和hashCode等方法
詳述:
我們再通過反編譯來看看當你定義一個case類時編譯器是怎麼做的:
同樣定義一個簡單的case類:
Person.scala
?
通過終端中編譯該檔案(scalac Person.scala)後生成兩個class檔案,Person.class和Person$.class
接下來再通過javap Person命令反編譯Person.class,結果結果如下:
?
再反編譯Person$.class
?
通過反編譯以上兩個class檔案可以知道,當你將一個類定義為case類後,編譯器就自動幫你實現了一系列方法。
我們再來對比下去掉case關鍵字將類定義為普通類後反編譯的結果
?
反編譯的結果如下:
?
比較之下case類比普通的類多了不少的方法,所以當你不需要這些額外的方法時你就可以將類定義為普通的類,但是你又不想通過new關鍵字來建立例項,你可以在普通類中實現apply方法達到此目的。
因為case本就旨在建立的是不可變資料,所以在使用模式匹配時顯得極為容易
case類在模式匹配和actor中經常使用到,當一個類被定義成為case類後,Scala會自動幫你建立一個伴生物件並幫你實現了一系列方法且帶來了不少好處,如下:
1.實現了apply方法,意味著你不需要使用new關鍵字就能建立該類物件 ?1 2 3 4 5 |
scala> case
class People(name:String,age:Int)
defined class
People
scala> val p = People( "mobin" , 22 )
//省略了new關鍵字
p: People = People(mobin, 22 )
|
1 2 |
scala> p match {
case People(x,y) => println(x,y) }
(mobin, 22 )
|
3.實現了類構造引數的getter方法(構造引數預設被宣告為val),但是當你構造引數是宣告為var型別的,它將幫你實現setter和getter方法(不建議將構造引數宣告為var)
構造引數為val的情況(預設): ?1 2 3 4 5 6 |
scala> p.name
res0: String = mobin
scala> p.name =
"mobin1" //報錯,因為構造引數被宣告為val所以並沒有幫你實現setter方法 <console>: 10 : error: reassignment to val
p.name = "mobin1"
|
1 2 3 4 5 6 7 8 9 10 11 |
scala> case
class People(var name:String)
//引數被宣告為var
defined class
People
scala> val p = People( "mobin" )
p: People = People(mobin)
scala> p.name =
"mobin2"
p.name: String = mobin2 scala> p.name
res1: String = mobin2
//修改成功,並沒有報錯
|
1 |
case
class Person(name: String,age : Int)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Compiled from
"Person.scala"
public
class com.mobin.scala.Person implements
scala.Product,scala.Serializable {
public
static scala.Function1<scala.Tuple2<java.lang.String, java.lang.Object>, com.mobin.scala.Person> tupled();
public
static scala.Function1<java.lang.String, scala.Function1<java.lang.Object, com.mobin.scala.Person>> curried();
public
java.lang.String name();
public
int age();
public
com.mobin.scala.Person copy(java.lang.String, int );
public
java.lang.String copy$ default $ 1 ();
public
int copy$ default $ 2 ();
public
java.lang.String productPrefix();
public
int productArity();
public
java.lang.Object productElement( int );
public
scala.collection.Iterator<java.lang.Object> productIterator();
public
boolean canEqual(java.lang.Object);
public
int hashCode();
public
java.lang.String toString();
public
boolean equals(java.lang.Object);
public
com.mobin.scala.Person(java.lang.String, int );
}
|
1 2 3 4 5 6 7 8 9 |
Compiled from
"Person.scala"
public
final class com.mobin.scala.Person$
extends scala.runtime.AbstractFunction2<java.lang.String, java.lang.Object, com.mobin.scala.Person>
implements scala.Serializable {
public
static final com.mobin.scala.Person$ MODULE$;
public
static {};
public
final java.lang.String toString();
public
com.mobin.scala.Person apply(java.lang.String, int );
public
scala.Option<scala.Tuple2<java.lang.String, java.lang.Object>> unapply(com.mobin.scala.Person);
public
java.lang.Object apply(java.lang.Object, java.lang.Object);
}
|
1 |
class
Person(var name : String,var age : Int) //將引數宣告為var
|
1 2 3 4 5 6 7 8 |
Compiled from
"Person.scala"
public
class com.mobin.scala.Person {
public
java.lang.String name();
public
void name_$eq(java.lang.String);
public
int age();
public
void age_$eq( int );
public
com.mobin.scala.Person(java.lang.String, int );
}
|