class Student {
//使用var定義一個可變的成員變量
var age=18
//使用val定義一不可變的成員變量
val name="zy"
//定義一個私有化成員變量(伴生對象仍然可以訪問)
private var id=1001
//定義一個私有化成員變量(伴生對象也不可以訪問)
private[this] val address="anhui"
//定義一個成員方法
def running(): Unit ={
println(this.name+"跑~")
}
}
注意點:
? - 在scala中聲明類不要指定public,scala的文件名可以與類名不同。
? - 成員屬性是否可以修改,取決于是否使用val修飾
? - 成員方法和屬性能不能被訪問,取決于修飾符,public(默認),private
//在類上聲明的是主構造器
class Student(val name:String,val age:Int) {
//使用this為方法名,這個是輔助構造器
def this(name:String,age:Int){
this(name,age)
}
}
主構造器的注意點:
? - 在類上定義的構造器稱為主構造器
? - 主構造器包含了整個所有的類的代碼塊,所以,默認的定義的類中的所有能執行的代碼都會執行
? - 主構造器中的參數如果沒有使用任何修飾符,默認的就是 private[this] val
? - 主構造器中的參數如果使用val或者var修飾,就相當于一個普通的成員變量
輔助構造器的注意點:
? - 當主構造器被class private Student()修飾了,可以使用輔助構造器創建該類對象
? - 輔助構造器必須使用def修飾,并且方法名為this
? - 輔助構造器中的參數不能使用var或者val 修飾
? - 輔助構造器中的第一行代碼必須是:調用其他的構造器
//使用private修飾主構造器,表示私有化類
class Student private(val name: String, val age: Int) {
def this(name: String, age: Int) {
this(name,age)
}
}
//使用 private[this]私有化類
class Person private[this](val name: String, val age: Int) {
}
注意點:
? - 被private修飾的類,被私有化,不能其他類不能創建該類實例,但是伴生對象可以
? - 如果想讓伴生對象都不能創建該類的實例,可以使用:class private[this]
? - 當主構造器被class private Student()修飾了,可以使用輔助構造器創建該類對象
??
?在scala的類中,與類名相同的單例對象叫做伴生對象。
? 特點:(假設現在有一個類:class Student ,和一個伴生對象:object Student)
? ? - class Student是object Student的伴生類
? ? - object Student是class Student的伴生對象
? ? - 類和伴生對象之間可以相互訪問私有的方法和屬性
? ? - 伴生類和伴生對象的名稱相同
例:
//使用private修飾主構造器,表示私有化類
class Student private {
private val name="zs"
private val age=18
}
object Student{
//在伴生對象中創建私有化類的對象
val student=new Student()
//在伴生對象中訪問私有化的屬性
val name=student.name
val age=student.age
}
單例對象:
單例對象表示,被object修飾,但是沒有自己的伴生類。
例:
object person{
val name="zs"
val age=18
}
特點:
? - scala 語言并不支持靜態成員,沒有靜態方法和靜態字段,Scala 通過單例對象 object 來解決
? - 單例對象中的所有成員和方法都是static的
? - 單例對象它本身就是一個單例,(因為不需要去 new)
apply方法
? 在講集合和數組的時候,可以通過 val intList=List(1,2,3)這種方式創建初始化一個列表對象, 其實它相當于調用 val intList=List.apply(1,2,3),只不過 val intList=List(1,2,3)這種創建方式更簡潔一點,但我們必須明確的是這種創建方式仍然避免不了 new,它后面的實現機制仍然是 new 的方式,只不過我們自己在使用的時候可以省去 new 的操作。通常我們會在類的伴生對象中定義 apply 方法,當遇到【類名(參數 1,...參數 n)】時 apply 方法會被調用。
? Apply也叫構建函數:把一堆零散的值構建成一個對象返回。
例:
object Test01 {
def main(args: Array[String]): Unit = {
//以下兩種方式創建對象等效
val list01 = List(1, 2, 3)
val list02 = List.apply(1, 2, 3)
}
}
特點:
? - apply方法只能定義在object中。
? - apply方法可以重載, 還是被系統自動調用的
?
? 定義:抽象類是一種不能被實例化的類,抽象類中包括了若干不能完整定義的方法,這些方法由子 類去擴展定義自己的實現。
? 特點:
? ? - 如果在父類中,有某些方法無法立即實現,而需要依賴不同的子類來覆蓋,重寫實現自 己不同的方法實現。此時可以將父類中的這些方法不給出具體的實現,只有方法簽名,這 種方法就是抽象方法。
? ? - 一個類中如果有一個抽象方法,那么類就必須用 abstract 來聲明為抽象類,此時抽象 類是不可以實例化的
? ? - 在子類中覆蓋抽象類的抽象方法時,不需要使用 override 關鍵字
例:
abstract class Annimal {
def runing()
def eat()
}
class Cat extends Annimal {
def runing(): Unit = {
println("running~")
}
def eat(): Unit = {
println("eatting~")
}
}
?
例:
//父類
class Annimal {
//被final修飾的無法被繼承
final private val name = "Annimal"
def runing(): Unit = {
println("running~")
}
def eat(): Unit = {
println("eatting~")
}
}
//子類
class Cat extends Annimal {
//重寫父類的方法
override def runing(): Unit = {
//調用父類原有的方法
super.runing()
}
}
注意:
? - 在 Scala 中擴展類的方式 和 Java 一樣都是使用 extends 關鍵字
? - 繼承就代表,子類可以從父類繼承父類的 field 和 method;然后子類可以在自己內部放 入父類所沒有,子類特有的 field 和 method;使用繼承可以有效復用代碼
? - 子類可以覆蓋父類的 field 和 method;但是如果父類用 final 修飾,field 和 method 用 final 修飾,則該類是無法被繼承的,field 和 method 是無法被覆蓋的
? - 如果子類要重寫一個父類中的非抽象方法,則必須使用 override 關鍵字
? - 使用 super 關鍵字,顯式地指定要調用父類的方法/屬性
?
例:
object Test01 {
def main(args: Array[String]): Unit = {
val parent=new Annimal //父類
val chrild=new Cat //子類
//類型判斷
println(chrild.isInstanceOf[Annimal]) //true
//類型獲取
println(classOf[Cat]) //class Cat
//類型轉換
val annimal: Annimal = chrild.asInstanceOf[Annimal]
}
}
//父類
class Annimal {
//被final修飾的無法被繼承
final private val name = "Annimal"
def runing(): Unit = {
println("running~")
}
def eat(): Unit = {
println("eatting~")
}
}
//子類
class Cat extends Annimal {
//重寫父類的方法
override def runing(): Unit = {
//調用父類原有的方法
super.runing()
}
}
?
? Scala 和 Java 語言一樣,采用了很強的限制策略,避免了多繼承的問題。在 Java 語言中,只允許繼承一個超類,該類可以實現多個接口,但 Java 接口有其自身的局限性:接口中只能包括抽象方法,不能包含字段、具體方法。Scala 語言利用 trait 解決了該問題,在 Scala 的 trait 中,它不但可以包括抽象方法還可以包含字段和具體方法。特質在底層實現是采用的Java的抽象類。
例:
trait Annimal {
val name = "Annimal"
def runing(): Unit = {
println("running~")
}
def eat()
}
特質的特點:
? - 特質里面的方法既可以實現,也可以不實現
? - 優先使用特質。一個類擴展多個特質是很方便的,但卻只能擴展一個抽象類。
? - 特質不能設置帶參數的構造:trait t(i: Int) {},參數 i 是非法的
? - 如果繼承多個特質,使用第一個特質使用 extends,后面的使用 with
例:
trait Car {
}
trait Person{
}
class transformers extends Car with Person{
}
? 將特質中的方法全部定義成為抽象方法。類可以使用extends的方式繼承特質。scala 不支持對類進行多繼承,但是支持多重繼承 trait,使用 with 關鍵字即可。類繼承 trait 后,必須實現其中的抽象方法,實現時不需要使用 override 關鍵字。
例:
trait MySQLDAO{
val id:Int
def add(o:Any):Boolean
def update(o:Any):Int
def query(id:String):List[Any]
}
//如果有多個 trait 的話,則使用 with 關鍵字即可
class DaoImpl extends MySQLDAO with Serializable{
// 給父類中的抽象字段賦值。
override val id = 12
// 實現抽象方法
def add(o:Any):Boolean = true
def update(o:Any):Int = 1
def query(id:String):List[Any] = List(1,2,3)
}
? 有時我們可以在創建類的對象時,指定該對象混入某個 Trait,這樣,就只有這個對象混入該 Trait 的方法,而類的其他對象則沒有。
例:
object Test01 {
def main(args: Array[String]): Unit = {
//會某一個對象混入特質
var HTQ_DHF =new Person() with DHF
}
}
trait transformers
trait HTQ extends transformers
trait DHF extends transformers
trait Person extends HTQ
? scala 中支持讓類繼承多個 Trait 后,依次調用多個 Trait 中的同一個方法,只要讓多個 Trait 的同一個方法中,在最后都執行 super.方法 即可。類中調用多個 Trait 中都有的這個方法時,首先會從最右邊的 Trait 的方法開始執行,然后依 次往左執行,形成一個調用鏈條這種特性非常強大,其實就相當于設計模式中的責任鏈模式的一種具體實現依賴。
例:
object Test01 {
def main(args: Array[String]): Unit = {
val p=new Person_TraitChain("zhangxiaolong")
p.sayHello
}
}
trait Handler {
//父類的trait 必須有實現體,不然會報錯
def handler(data:String): Unit ={
println("Handler :"+data)
}
}
trait Handler_A extends Handler{
override def handler(data:String): Unit = {
println("Handler_A :"+data)
super.handler(data)
}
}
trait Handler_B extends Handler{
override def handler(data:String): Unit = {
println("Handler_B :"+data)
super.handler(data)
}
}
trait Handler_C extends Handler{
override def handler(data:String): Unit = {
println("Handler_C :"+data)
super.handler(data)
}
}
class Person_TraitChain(val name:String) extends Handler_C with Handler_B with
Handler_A{
def sayHello={
println("Hello "+name)
handler(name)
}
}
結果會打?。?br/>
從右向左,依次調用
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。