關於Scala和麪向對象的函數式編程

這是一個很好的Scala的入門介紹,原文:http://my.oschina.net/mup/blog/363436前端

定義express

Scala語言是一種面嚮對象語言,同時又結合了命令式(imperative)和函數式(functional)編程風格。官網描述:Object-Oriented Meets Functional(面向對象遇到函數式編程)。編程

安裝數組

下載地址http://www.scala-lang.org/download/服務器

當前版本2.11.4app

設置環境變量編程語言

?ide

1
2
export SCALA         _         HOME         =         /home/mupeng/Hadoop/scala-         2.11         .         4
export PATH         =         $SCALA         _         HOME/bin         :         $PATH

若是是修改的profile,執行source /etc/profile,使環境變量當即生效。
函數式編程

檢測安裝是否成功命令 scala -version,若是出現如下內容,證實安裝成功。函數

?

1
2
scala -version
Scala code runner version          2.11         .         4          -- Copyright          2002         -         2013         , LAMP/EPFL

Scala解釋器

直接輸入scala,就進入scala解釋器

?

1
2
3
4
scala
Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35).
Type          in          expressions to have them evaluated.
Type :help          for          more          information.

先來兩個例子,熟悉如下scala解釋器

?

1
2
scala> 1+2
res0: Int = 3

結果被命名爲res0,Int指結果類型,3指計算結果

?

1
2
scala> println(         "hello scala"         )
hello scala

輸出hello scala

變量

Scala中的變量有兩種varval(val相似於Java中final,值不可改變)

scala> var hello = "hello world"

hello: String = hello world

scala能夠根據賦值內容推算出變量類型。Scala中的數據類型都是對象。

函數

Scala是面嚮對象語言同時也是函數式編程語言,所以函數在Scala語言中的地位同對象、變量同樣。使用scala函數注意一下幾點:

1) 函數參數寫在類型以前,中間用逗號隔開;

?

1
2
3
def          helloScala          =          {
             println(         "Hello Scala!"         )
}

2) 函數都有返回結果,無需使用return,函數內最後一個表達式做爲返回結果返回。helloScala函數的返回類型爲Unit,表示該函數不返回任何有意義的值(至關於Java中的void)。

3) 函數參數能夠給定默認值。

?

1
2
3
def          hello(name          :          String          =          "Scala"                 :          String          =          {
             return          "Hello : "          + name
}

4) 函數的參數都是val類型,執行過程當中不能被改變。(函數式編程的特色,只計算結果,不改變參數)

5) 定義方法還有以下方式

def add = (x : Int, y : Int) => x + y

打印結果print(add(1, 2));  

def add2(x : Int)(y : Int) = x + y

打印結果print(add2(1)(2))

循環

在瞭解循環以前,咱們先要知道Scala不支持i++和++i,須要使用i+=1來實現加一。

while循環

?

1
2
3
4
5
var          i         =         0
while          (i < args.length) {
           println (args(i))
           i+         =         1
}

for循環

?

1
2
for          (arg <-args)
           println(arg)

for參數裏面一樣支持if判斷,好比輸出1——10中的偶數

?

1
2
for          (i <-          1          to          10          if                  %          2          ==          0        
           println(i)

foreach

?

1
args.foreach(arg          =         > println(arg))

由於參數只有一個,表達式也只有一個,能夠簡寫爲

?

1
args.foreach(println)

Array與List

建立數組有兩種方式

?

1
2
3
4
val          greetStrings          =          new          Array[String](         3        
greetStrings(         0                 =          "Hello" 
greetStrings(         1                 =          ", " 
greetStrings(         2                 =          "world!\n"

或者

?

1
val          numNames          =          Array(         "zero"                 "one"                 "two"         )

注意與Java不一樣的是:數組的第零個元素是greetStrings(0),不是greetStrings[0]。

Array長度不可變,可是它的值可變。

List長度與值都不可變。

?

1
2
3
4
val          list         1          =          List(         1                 2         )
val          list         2          =          List(         3                 4         )
val          list         3          =          list         1          :::          list         2           //list3結果爲(1,2,3,4)
val          list         4          =          0          ::          list         3                //list4結果爲(0,1,2,3,4)

這裏有兩個操做 ::: 鏈接兩個List

:: 右操做符,將一個新元素放到List的最前端。

類與對象

1. 定義類

?

1
2
3
4
5
6
class          Person {
           var          email          =          "abc123@126.com"          // 變量,var聲明會生成getter和setter方法
           var          name          :          String          =          _          // 變量, _起到佔位符的做用
           val          age          =          10         ;                  // 常變量,val聲明只會生成getter
           private          val          gender          =          "male"          //只能在類內部使用
}

缺省訪問級別是public,一個源文件中能夠有多個class,都是public的。

2. 主構造器

?

1
2
3
class          Student(         var          name          :          String,          val          number          :          String) {
           println(         "主構造器!"         )
}

1)主構造器直接跟在類名後面,主構造器的參數最後會被編譯成字段。

2)主構造器執行的時候,會執行類中全部的語句。

3)若是主構造器參數聲明時候不加val或者var,就至關於private

3. 從構造器

?

1
2
3
4
5
6
7
8
class          Student(         var          name          :          String,          val          number          :          String) {
           println(         "主構造器!"         )
           var          gender          :          String          =          _
           def          this         (name          :          String, number          :          String, gender          :          String) {
             this         (name, number)
             this         .gender          =          gender
           }
}

1)從構造器定義在類內部,方法名爲this

2)從構造器必須先調用已經存在的構造器

4. 繼承:繼承而來的字段不須要加var或者val

?

1
2
3
class          UniversityStudent(name          :          String, number          :          String,          val          major          :          String)          extends          Student(name, number) {
           ......
}

注意:重寫父類的字段或方法要在前面加上override關鍵字

5. 抽象類(abstract class)與特質(trait)

1)抽象方法不須要加關鍵字,只有聲明,沒有具體實現。

2)能夠聲明抽象字段,也就是沒有初始值。

3)子類重寫父類的抽象方法或者抽象字段,不須要加override

trait特質能夠理解爲能夠有具體實現方法的接口,類能夠經過with關鍵字混入(mix-in)特質,同時它的對象也能夠混入特質。

Scala程序的執行入口是提供main方法的獨立單例對象。一樣也能夠給一個單例對象混入App特質,去繼承App特質中的main方法.

6. apply方法

1)對象的apply方法

?

1
2
3
4
5
6
7
8
9
10
class          ApplyTest {
           println(         "Test"         )
}
 
object          ApplyTest {
           def          apply()          =          new          ApplyTest
}
 
// 調用方法
val                  =          ApplyTest()          // 類名+括號,調用對象的apply方法

上面例子中一個調用apply方法,生成一個新的對象。(絕大多數apply方法都是這樣去用)

apply方法就是Scala提供的一個語法糖,對象的apply方法在scala裏面很是經常使用

例如:

?

1
2
3
4
5
val          arr          =          Array(         1                 2                 3         )
 
實際調用的是
 
val          arr          =          Array.apply(         1                 2                 3         )

如下是Array對象的apply方法源碼

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
object          Array          extends          FallbackArrayBuilding {
 
            ...
    
            /** Creates an array of `Int` objects */
           // Subject to a compiler optimization in Cleanup, see above.
           def          apply(x         :          Int, xs         :          Int*)         :          Array[Int]          =          {
             val          array          =          new          Array[Int](xs.length +          1         )
             array(         0                 =          x
             var                  =          1
             for          (x <- xs.iterator) { array(i)          =          x; i +         =          1          }
             array
           }
   
           ...
 
}

2)類的apply方法

?

1
2
3
4
5
6
7
8
9
class          ApplyTest {
           def          apply() {
             println(         "APPLY Method"         )
           }
           println(         "Test"         )
}
 
val                  =          new          ApplyTest
a()          // 對象名+括號,調用類的apply方法

7.單例

用object替換class,其它的跟定義類相似。

當單例對象與類共享同一個名字時,該對象稱做類的伴生對象。

與Java對比

若是用做服務器端開發,Scala的簡潔、靈活性是Java沒法比擬的;若是是企業級應用開發、Web開發,Java的強大是Scala沒法匹敵 的。咱們不用一種語言的優點去抨擊另外一種語言的短板,因此不要說Java與Scala孰優孰劣,更不要說誰將要取代誰,兩者原本就是互補關係。

總結

scala語言的知識點有太多太多,在一篇博客中不可能作到一一列舉。本文只是列舉了經常使用的的幾點,但願對正在學習scala的人有所幫助。

相關文章
相關標籤/搜索