溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Scala的面向?qū)ο?/h1>
發(fā)布時間:2020-07-12 13:13:52 來源:網(wǎng)絡(luò) 閱讀:378 作者:原生zzy 欄目:開發(fā)技術(shù)

1.scala的類

(1)類的成員

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(默認(rèn)),private


(2)類的構(gòu)造器

//在類上聲明的是主構(gòu)造器
class Student(val name:String,val age:Int) {
  //使用this為方法名,這個是輔助構(gòu)造器
  def this(name:String,age:Int){
    this(name,age)
  }
}

主構(gòu)造器的注意點:
? - 在類上定義的構(gòu)造器稱為主構(gòu)造器
? - 主構(gòu)造器包含了整個所有的類的代碼塊,所以,默認(rèn)的定義的類中的所有能執(zhí)行的代碼都會執(zhí)行
? - 主構(gòu)造器中的參數(shù)如果沒有使用任何修飾符,默認(rèn)的就是 private[this] val
? - 主構(gòu)造器中的參數(shù)如果使用val或者var修飾,就相當(dāng)于一個普通的成員變量
輔助構(gòu)造器的注意點:
? - 當(dāng)主構(gòu)造器被class private Student()修飾了,可以使用輔助構(gòu)造器創(chuàng)建該類對象
? - 輔助構(gòu)造器必須使用def修飾,并且方法名為this
? - 輔助構(gòu)造器中的參數(shù)不能使用var或者val 修飾
? - 輔助構(gòu)造器中的第一行代碼必須是:調(diào)用其他的構(gòu)造器


(3)類的私有化

//使用private修飾主構(gòu)造器,表示私有化類
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修飾的類,被私有化,不能其他類不能創(chuàng)建該類實例,但是伴生對象可以
? - 如果想讓伴生對象都不能創(chuàng)建該類的實例,可以使用:class private[this]
? - 當(dāng)主構(gòu)造器被class private Student()修飾了,可以使用輔助構(gòu)造器創(chuàng)建該類對象
??

2.伴生對象

?在scala的類中,與類名相同的單例對象叫做伴生對象。
? 特點:(假設(shè)現(xiàn)在有一個類:class Student ,和一個伴生對象:object Student)
? ? - class Student是object Student的伴生類
? ? - object Student是class Student的伴生對象
? ? - 類和伴生對象之間可以相互訪問私有的方法和屬性
? ? - 伴生類和伴生對象的名稱相同
例:

//使用private修飾主構(gòu)造器,表示私有化類
class Student private {
  private val name="zs"
  private val age=18
}
object Student{
  //在伴生對象中創(chuàng)建私有化類的對象
  val student=new Student()
  //在伴生對象中訪問私有化的屬性
  val name=student.name
  val age=student.age
}

單例對象
單例對象表示,被object修飾,但是沒有自己的伴生類。
例:

object person{
   val name="zs"
   val age=18
}

特點
? - scala 語言并不支持靜態(tài)成員,沒有靜態(tài)方法和靜態(tài)字段,Scala 通過單例對象 object 來解決
? - 單例對象中的所有成員和方法都是static的
? - 單例對象它本身就是一個單例,(因為不需要去 new)


apply方法
? 在講集合和數(shù)組的時候,可以通過 val intList=List(1,2,3)這種方式創(chuàng)建初始化一個列表對象, 其實它相當(dāng)于調(diào)用 val intList=List.apply(1,2,3),只不過 val intList=List(1,2,3)這種創(chuàng)建方式更簡潔一點,但我們必須明確的是這種創(chuàng)建方式仍然避免不了 new,它后面的實現(xiàn)機制仍然是 new 的方式,只不過我們自己在使用的時候可以省去 new 的操作。通常我們會在類的伴生對象中定義 apply 方法,當(dāng)遇到【類名(參數(shù) 1,...參數(shù) n)】時 apply 方法會被調(diào)用。
? Apply也叫構(gòu)建函數(shù):把一堆零散的值構(gòu)建成一個對象返回
例:

object Test01 {
  def main(args: Array[String]): Unit = {
    //以下兩種方式創(chuàng)建對象等效
    val list01 = List(1, 2, 3)
    val list02 = List.apply(1, 2, 3)
  }
}

特點
? - apply方法只能定義在object中。
? - apply方法可以重載, 還是被系統(tǒng)自動調(diào)用的
?

3.scala的抽象類

? 定義:抽象類是一種不能被實例化的類,抽象類中包括了若干不能完整定義的方法,這些方法由子 類去擴展定義自己的實現(xiàn)。
? 特點
? ? - 如果在父類中,有某些方法無法立即實現(xiàn),而需要依賴不同的子類來覆蓋,重寫實現(xiàn)自 己不同的方法實現(xiàn)。此時可以將父類中的這些方法不給出具體的實現(xiàn),只有方法簽名,這 種方法就是抽象方法。
? ? - 一個類中如果有一個抽象方法,那么類就必須用 abstract 來聲明為抽象類,此時抽象 類是不可以實例化的
? ? - 在子類中覆蓋抽象類的抽象方法時,不需要使用 override 關(guān)鍵字
例:

abstract class Annimal {
  def runing()

  def eat()
}

class Cat extends Annimal {
  def runing(): Unit = {
    println("running~")
  }
  def eat(): Unit = {
    println("eatting~")
  }
}

?

4.scala的繼承

例:

//父類
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 = {
    //調(diào)用父類原有的方法
    super.runing()
  }
}

注意
? - 在 Scala 中擴展類的方式 和 Java 一樣都是使用 extends 關(guān)鍵字
? - 繼承就代表,子類可以從父類繼承父類的 field 和 method;然后子類可以在自己內(nèi)部放 入父類所沒有,子類特有的 field 和 method;使用繼承可以有效復(fù)用代碼
? - 子類可以覆蓋父類的 field 和 method;但是如果父類用 final 修飾,field 和 method 用 final 修飾,則該類是無法被繼承的,field 和 method 是無法被覆蓋的
? - 如果子類要重寫一個父類中的非抽象方法,則必須使用 override 關(guān)鍵字
? - 使用 super 關(guān)鍵字,顯式地指定要調(diào)用父類的方法/屬性
?

5.scala的類型檢查和轉(zhuǎn)換

Scala的面向?qū)ο?><br/>例:</p>
<pre><code>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
    //類型轉(zhuǎn)換
    val annimal: Annimal = chrild.asInstanceOf[Annimal]
  }
}

//父類
class Annimal {
  //被final修飾的無法被繼承
  final private val name =

?

6.scala的特質(zhì) (Trait)

(1)特質(zhì)的介紹

? Scala 和 Java 語言一樣,采用了很強的限制策略,避免了多繼承的問題。在 Java 語言中,只允許繼承一個超類,該類可以實現(xiàn)多個接口,但 Java 接口有其自身的局限性:接口中只能包括抽象方法,不能包含字段、具體方法。Scala 語言利用 trait 解決了該問題,在 Scala 的 trait 中,它不但可以包括抽象方法還可以包含字段和具體方法。特質(zhì)在底層實現(xiàn)是采用的Java的抽象類。
例:

trait Annimal {
  val name = "Annimal"

  def runing(): Unit = {
    println("running~")
  }
  def eat()
}

(1)特質(zhì)的基本使用

特質(zhì)的特點
? - 特質(zhì)里面的方法既可以實現(xiàn),也可以不實現(xiàn)
? - 優(yōu)先使用特質(zhì)。一個類擴展多個特質(zhì)是很方便的,但卻只能擴展一個抽象類。
? - 特質(zhì)不能設(shè)置帶參數(shù)的構(gòu)造:trait t(i: Int) {},參數(shù) i 是非法的
? - 如果繼承多個特質(zhì),使用第一個特質(zhì)使用 extends,后面的使用 with
例:

trait Car {
}
trait Person{

}
class transformers extends Car with Person{

}

(2)特質(zhì)作為接口使用

? 將特質(zhì)中的方法全部定義成為抽象方法。類可以使用extends的方式繼承特質(zhì)。scala 不支持對類進行多繼承,但是支持多重繼承 trait,使用 with 關(guān)鍵字即可。類繼承 trait 后,必須實現(xiàn)其中的抽象方法,實現(xiàn)時不需要使用 override 關(guān)鍵字。
例:

trait MySQLDAO{
val id:Int
def add(o:Any):Boolean
def update(o:Any):Int
def query(id:String):List[Any]
}
//如果有多個 trait 的話,則使用 with 關(guān)鍵字即可
class DaoImpl extends MySQLDAO with Serializable{
// 給父類中的抽象字段賦值。
override val id = 12
// 實現(xiàn)抽象方法
def add(o:Any):Boolean = true
  def update(o:Any):Int = 1
def query(id:String):List[Any] = List(1,2,3)
}

(3)為實例對象混入 Trait

? 有時我們可以在創(chuàng)建類的對象時,指定該對象混入某個 Trait,這樣,就只有這個對象混入該 Trait 的方法,而類的其他對象則沒有。
例:

object Test01 {
  def main(args: Array[String]): Unit = {
    //會某一個對象混入特質(zhì)
    var HTQ_DHF =new Person() with DHF
  }
}
trait transformers
trait HTQ extends transformers
trait DHF extends transformers
trait Person extends HTQ

(4)Trait 調(diào)用鏈

? scala 中支持讓類繼承多個 Trait 后,依次調(diào)用多個 Trait 中的同一個方法,只要讓多個 Trait 的同一個方法中,在最后都執(zhí)行 super.方法 即可。類中調(diào)用多個 Trait 中都有的這個方法時,首先會從最右邊的 Trait 的方法開始執(zhí)行,然后依 次往左執(zhí)行,形成一個調(diào)用鏈條這種特性非常強大,其實就相當(dāng)于設(shè)計模式中的責(zé)任鏈模式的一種具體實現(xiàn)依賴。
例:

object Test01 {
  def main(args: Array[String]): Unit = {
    val p=new Person_TraitChain("zhangxiaolong")
    p.sayHello
  }
}

trait Handler {
  //父類的trait 必須有實現(xiàn)體,不然會報錯
  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)
  }
}

結(jié)果會打?。?br/>Scala的面向?qū)ο?><br/>從右向左,依次調(diào)用</p>
													            </div>
            <div   id=向AI問一下細節(jié)

推薦閱讀:
  1. Scala的actor
  2. Scala的泛型

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI