【圖文詳細 】Scala——類
阿新 • • 發佈:2018-12-24
1、Scala 類
Scala 的類與 Java、C++的類比起來更簡潔,學完之後你會更愛 Scala!!!
1.1、定義類
定義一個 Student 類:
package com.mazh.scala.day2.oop // 在 Scala 中,類並不用宣告為 public 。 // 在 Scala 檔案中,檔名可以不用和類名一致 //Scala 原始檔中可以包含多個類,所有這些類都具有公有可見性 class Person { // 用 val 修飾的變數是隻讀屬性,有 getter 但沒有 setter // (相當與 Java 中用 final 修飾的變數) val id = "100" /** * 作者: 李濤: https://blog.csdn.net/qq_42246689 */ // 用 var 修飾的變數既有 getter 又有 setter var age: Int = 33 // 類私有欄位 , 只能在 當前 類的內部或伴生物件中使用 private var name: String = "黃渤" // 物件私有欄位 , 訪問許可權更加嚴格的, Person 類的方法只能訪問到當前物件的欄位 // 伴生物件都不能訪問 private[this] val nickname = "影帝" }
通過反編譯工具反編譯之後看到:
package com.mazh.scala.util; public class Person { private final String id = "100"; private int age = 33; private String name = "黃渤"; private final String nickname = "影帝"; // 相當於 id屬性的 getId() 方法 public String id() { return this.id; } // 相當與 age屬性的 getAge() 方法 public int age() { return this.age; } // 相當與 age屬性的 setAge方法 public void age_$eq(int x$1) { this.age = x$1; } // name屬性的私有 get方法 private String name() { return this.name; } // name屬性的私有 set方法 private void name_$eq(String x$1) { this.name = x$1; } }
通過 JDK 自帶的反編譯工具反編譯:
C:\IdeaProjects-2017-02-07\ScalaTest\out\production\ScalaTest\com\mazh\scala\day2\oop>java p -private Person 警告: 二進位制檔案 Person 包含 com.mazh.scala.day2.oop.Person Compiled from "Person.scala" public class com.mazh.scala.day2.oop.Person { private final java.lang.String id; private int age; private java.lang.String name; private final java.lang.String nickname; public java.lang.String id(); public int age(); public void age_$eq(int); private java.lang.String name(); private void name_$eq(java.lang.String); public com.mazh.scala.day2.oop.Person(); }
下面這張圖給出了 setter 和 getter 方法的生成關係:
1.2、定義構造器
注意:主構造器會執行類定義中的所有語句
定義一個 Student 類:
package com.mazh.scala.day2.oop
import java.io.IOException
/**
* 每個類都有主構造器,主構造器的引數直接放置類名後面,與類交織在一起 * 主構造器會執行類定義中的所有語句
* 當在創 建物件時,需要進行相關初始化操作時,可以將初始化語句放在類體中
* 同樣也可以在類中新增或重寫相關方法
*/
class Student(val name: String, val age: Int){
println("執行主構造器")
try {
println("讀取檔案")
throw new IOException("io exception")
} catch {
case e: NullPointerException => println("列印異常 Exception : " + e)
case e: IOException => println("列印異常 Exception : " + e)
} finally {
println("執行 finally 部分")
}
private var gender = "male"
// 用 this關鍵字定義輔助構造器
def this(name: String, age: Int, gender: String){
// 每個輔助構造器必須以主構造器或其他的輔助構造器的呼叫開始
this(name, age)
println("執行輔助構造器")
this.gender = gender
}
}
定義輔助構造器:
如果禁用掉了主構建器(使用 private 宣告),則必須使用輔助建構函式來建立物件。
輔助建構函式具有兩個特點:
1、輔助構建器的名稱為 this,Java 中的輔助建構函式與類名相同,這常常會導致修改類名 時出現不少問題,scala 語言避免了這樣的問題;
2、呼叫輔助建構函式時,必須先呼叫主建構函式或其它已經定義好的建構函式。
定義一個 Queen 類:
package com.mazh.scala.day2.oop
// 構造器引數可以不帶 val或 var ,
// 如果不帶 val或 var的引數至少被一個方法所使用 , 那麼它將會被提升為欄位
// 在類名後面加 private就變成了私有的 ,相當於 禁用了主構造器
class Queen private(val name: String, prop: Array[String], private var age: Int = 18){
println(prop.size)
//prop被下面的方法使用後, prop就變成了不可變的 物件私有欄位,
// 等同於 private[this] val prop
// 如果沒有被方法使用該引數將不被儲存為欄位
// 僅僅是一個可以被主構造器中的程式碼訪問的普通引數
def description = name + " is " + age + " years old with " + prop.toBuffer
}
object Queen{
def main(args: Array[String]) {
// 私有的構造器,只有在其伴生物件中使用
val q = new Queen("劉亦菲", Array("女神", "女神經"), 20)
println(q.description())
}
}
總結: 主構造方法:
1、與類名交織在一起
2、主構造方法執行,導致類名後面的大括號裡面的程式碼都會執行
輔助構造方法:
1、名字必須叫 this
2、必須以呼叫主構造方法或者是其他輔助構造方法開始
3、裡面的屬性不能寫修飾符