Java 中 靜態成員是對應類的,所以既可以通過對象名,也可以通過類名訪問,但不能訪問非靜態方法或變量;位於“數據區”,無論多少個對象該變量在內存中都只有一份;
Java中非靜態成員是對應對象的,每個對象都會有一個,所以只能通過對象名引用;位於“堆空間”,每new一個對象創建一份,因此有多少個對象該變量在內存就有多少份;
scala中沒有靜態方法和屬性,全部由singleton object(單例對象)來替代;
******************************
java的interface只定義方法名稱和參數列表,不能定義方法體; 實現接口用implement;trait可以看作有方法實現和字段的interface;代表一類事物的特性
Scala 中trait則可以定義方法體,即 可以包含方法的接口;實現trait 用extends;scala可以在一個class實例化的時候混合進一個trait, 並通過用with 對其進行包裝;
*********************************
val evenNumbers = List(2, 4, 6, 8, 10)
evenNumbers.foldLeft(0) { (a: Int, b:Int) => a + b }
可以利用 Scala 的參數類型推測功能 將上面操作簡化爲:evenNumbers.foldLeft(0) { (a, b) => a + b } 甚至可以簡化爲 evenNumbers.foldLeft(0) { _ + _ }
********************************************
模式匹配的基本思想就是試圖對一個值進行多種模式的匹配,並且在匹配的同時將匹配值拆分成若干子項,最後對匹配值與其子項執行某些代碼;
case classes
- 編譯器爲case class生成一個同名的對象構造器(Factory Method),也就是你可以使用 Var(“x”) 來創建一個類的實例,而無需使用new Var(“x”).-->可以省略 new 關鍵字
- Scala prefixes all the parameters with val,
- A companion object is created with the appropriate apply method
- The compiler adds a method called unapply
- Scala編譯器爲case class的構造函數的參數創建以參數名爲名稱的屬性,比如Val的類的參數name:String 可以直接通過 .name訪問;.-->即自動添加 getter 方法
- 編譯器爲case class 構造了更自然的toString,hashCode和equals實現,它們會遞歸打印,比較case class的參數屬性;-->這些實現可以按照值區別類實例是否相等,從而方便進行 模式匹配
- Scala編譯器爲case class添加了一個Copy方法,這個copy方法可以用來構造類對象的一個可以修改的拷貝。這對於使用已有的對象構造一個新實例非常方便,你只要修新創建實例的某些參數即可。
- eg
這個程序的目標是處理一些由整數常量、變量和加號組成的簡單的算數表達式,例如1 + 2 和 (x + x ) + (7 + y )。
abstract class Treecase class Sum(l: Tree, r: Tree) extends Treecase class Var(n: String) extends Treecase class Const(v: Int) extends Tree我們實際上定義了三個條件類 Sum ,Var 和 Const 。表示我們算數表達式的數據類型.
下面給他們定義對應的操作。我們將會首先編寫一個在上下文中下計算表達式的函數。這裏的上下文指的是變量與值的綁定關係。例如表達式x+1在x=5上下文中應該得出結果6。
type Environment = String => Int現在我們可以開始定義求值函數了。
def eval(t: Tree, env: Environment): Int = t match {
case Sum(l, r) => eval(l, env) + eval(r, env)
case Var(n) => env(n)
case Const(v) => v
}
********************************************
Scala的Option類型可以避免這種情況,因此Scala應用推薦使用Option類型來代表一些可選值。使用Option類型,讀者一眼就可以看出這種類型的值可能爲None。
在寫模式匹配時,爲保證可選項覆蓋了全部的可能性,這時可以爲基類添加上Sealed關鍵字,這樣你就只需要關心已經定義的子類,如果可選項不去全,編譯器會自動警告。
**********************************************
case class 的優點
- match是表達式,不是語句,所以是有返回值的,
- 在模式中使用變量可能會與常量衝突,因此變量要以小寫字母開始。如果有常量是小寫字母開頭的,那麼需要用反引號將常量名包起來
case class 的用處:
- 用於替換 tuples
- val p = ("qh",20) // p._1 = "qh", p._2 = 20;好處是簡潔,但無意義
- case class person(name:String, age:Int)
val p = person("qh",20) // p.name = "qh", p.age = 20; 好處是有名字,自說明,可讀性強
- val p = ("qh",20) // p._1 = "qh", p._2 = 20;好處是簡潔,但無意義