1. 程式人生 > >【圖文詳細 】Scala——物件

【圖文詳細 】Scala——物件

2、Scala 物件 

 

2.1、單例物件 
在某些應用場景下,我們可能不需要建立物件,而是想直接呼叫方法,但是 Scala 語言並不 支援靜態成員,沒有靜態方法和靜態欄位,Scala 通過單例物件 object 來解決該問題

1、存放工具方法和常量

2、高效共享單個不可變的例項

3、單例模式

package com.mazh.scala.day2.oop 
 
import scala.collection.mutable.ArrayBuffer 
 
/** 
  * 作者: 李濤 https://blog.csdn.net/qq_42246689 
  */ 
object SingletonDemo { 
  def main(args: Array[String]) { 
    // 單例物件,不需要 new ,用【類名 . 方法】呼叫物件中的方法
     val session = SessionFactory.getSession() 
    println(session) 
  } 
} 
 
object SessionFactory{ 
 
  // 該部分相當於 java中的靜態塊 
 var counts = 5 
  val sessions = new ArrayBuffer[Session]() 
  while(counts > 0){ 
    sessions += new Session 
    counts -= 1 
  } 
 
  // 在 object中的方法相當於 java中的靜態方法 
  def getSession(): Session ={ 
    sessions.remove(0) 
  } 
} 
 
class Session{ 
 
} 

總結:

1、object 裡面的方法都是靜態方法

2、object 裡面的欄位都是靜態欄位

3、它本身就是一個單例,(因為不需要去 new) 

 

2.2、伴生物件 
在 Scala 的類中,與類名相同的單例物件叫做伴生物件,也就是說如果我們在 object Dog 所 在的檔案內定義了一個 class Dog,此時:

1、 object Dog 被稱為 class Dog 的伴生物件

2、 class Dog 被稱為 object Dog 的伴生類

3、 類和伴生物件之間可以相互訪問私有的方法和屬性 

package com.mazh.scala.day2.oop 
 
/** 
  * 作者: 李濤 https://blog.csdn.net/qq_42246689
  */ 
class Dog { 
  val id = 100
   private var name = "旺財" 
 
  def printName(): Unit ={ 
    // 在 Dog類中可以訪問伴生物件 Dog的私有屬性 
    println(Dog.CONSTANT + name ) 
  } 
} 
/** 
  * 伴生物件
  */ 
object Dog { 
 
  // 伴生物件中的私有屬性
   private val CONSTANT:String = "汪汪汪: " 
 
  def main(args: Array[String]) { 
    val p = new Dog 
    // 訪問私有的欄位 name 
    p.name = "123" 
    p.printName() 
  } 
}

總結: 伴生類 和 伴生物件 之間可以互相訪問對方的私有屬性 

 

2.3、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 方法會被呼叫。

package com.mazh.scala.day2.oop 
 
object ApplyDemo { 
 
  def main(args: Array[String]) { 
 
    // 呼叫了 Array伴生物件的 apply方法 
    //def apply(x: Int, xs: Int*): Array[Int] 
    //arr1 中只有一個元素 5 
    val arr1 = Array(5) 
    println(arr1.toBuffer) 
 
    //new了一個長度為 5的 array ,數組裡麵包含 5個 null 
    var arr2 = new Array(5) 
println(arr2.toBuffer) 
  } 
}

 缺點: 無法為該類的執行,從外部傳入引數,也既沒有 main 方法的引數可用 

 

2.4、應用程式物件 App 
Scala 程式都必須從一個物件的 main 方法開始,可以通過擴充套件 App 特質,不寫 main 方法。

package com.mazh.scala.day2.oop 
 
/** 
  * 作者: 李濤 https://blog.csdn.net/qq_42246689 
  */ 
object AppObjectDemo extends App{ 
  // 不用寫 main方法 
  println("I love Scala") 
} 

缺點: 無法為該類的執行,從外部傳入引數,也既沒有 main 方法的引數可用 

2.5、抽象類 

抽象類是一種不能被例項化的類,抽象類中包括了若干不能完整定義的方法,這些方法由子 類去擴充套件定義自己的實現。

1、如果在父類中,有某些方法無法立即實現,而需要依賴不同的子類來覆蓋,重寫實現自 己不同的方法實現。此時可以將父類中的這些方法不給出具體的實現,只有方法簽名,這 種方法就是抽象方法。

2、而一個類中如果有一個抽象方法,那麼類就必須用 abstract 來宣告為抽象類,此時抽象 類是不可以例項化

3、在子類中覆蓋抽象類的抽象方法時,不需要使用 override 關鍵字 

package com.mazh.scala.day2.oop 
 
/** 
  * 作者: 李濤 https://blog.csdn.net/qq_42246689 
  * 描述: 定義抽象類 
  */ 
abstract class Animal { 
  // 抽象欄位 ( 域)
   // 前面我們提到,一般類中定義欄位的話必須初始化,而抽象類中則沒有這要求
   var height:Int 
  // 抽象方法
   def eat:Unit 
} 
 //Person繼承 Animal ,對 eat方法進行了實現 
// 通過主構造器對 height引數進行了初始化 
class Person(var height:Int) extends Animal{ 
 
  // 對父類中的方法進行實現,注意這裡面可以不加 override關鍵字 
  def eat()={ 
    println("eat by mouth") 
  } 
} 

總結: Scala 抽象類的使用方式和 Java 中的抽象類的概念一致