閱讀837 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Scala 學習

首先很奇怪為什麼雲棲社區不可以上傳資料??
Why?

1.強類型語言 弱類型語言
強類型語言:定義對象或變量時,需要指定其歸屬類型
一旦一個變量類型確定,它所歸屬的類型不可再變
弱類型語言:定義變量時不用指定變量類型
在程序運行中,可以改變變量的的歸屬類型
scala變量定義:
var str = "abcd"
java: String str = "abcd"
這樣寫法不是沒有指定str的類型,而是沒有顯式的指定str的類型,它隱式的從變量值中自動判斷
顯式寫法:
var str:String = "abcd"

2.聲明變量有兩種修飾符
var: 變量可被重新賦值
val: (常量)不可被重新賦值
在編程過程中,能使用val的地方不要使用var
3.基礎數據類型
java基礎數據類型,它對應的變量,不是對象,不能通過"."運算符來訪問對象的方法
scala對應java的基礎數據類型的類型,對應的變量,是對象,可以通過“.”調用對象的屬性或方法
4.String類型的字麵量
val s1 = "abcd"
val s2 = "ab\"cd"
val s3 = """ab".eo24/.*cd"""

字符串模板嵌套
println(s"name:$name,age:$age")
println(s"name:$name,age:${age}aa")
println(s"""name:$name
| age:$age
| over
| """
| )
5.基礎數據類型之間的轉換方法

對象.to類型
123.toDouble
"123".toInt
445.33.toString
6.scala中的運算符
scala中運算符不是語法,而是函數(對象)
a+b 等同於 a.+(b)
前者是後者的簡寫
當一個對象通過點調用其方法的時候,如果該方法隻有1個參數,那麼點號可以省略 小括號可以省略,對象、方法、參數之間用空格隔開即可
如果方法有多個參數,那麼點號可以省略,但是小括號不能省略

==運算符(Java)
String a = new String("abc")
String b = a
a == b

==在scala中方法,這個方法等同於equal方法
val a = new String("abc")
val b = new String("abc")

a == b a.equal(b)

scala中沒有基礎數據類型的++ --運算符
7.標識符 符合java的規範
類標識符,駝峰式命名首字母大寫
變量 方法標識符,駝峰式命名,首字母小寫
包標識符,全小寫,層級使用點分割

val在scala中雖然定義的是常量,但是,一般都用變量的規則來命名標識符
8.scala注釋規則和java一致
9.語句塊
java中的語句塊全部都是過程,沒有返回值,隻有方法語句塊中用return才能有返回值
scala中大部分的語句塊都是有返回值的,而且不需要return
java中語句塊的作用主要用來劃分作用域
scala中的語句塊除了劃分作用域之外還可以帶返回值

val str1 = "111"
val str2 = {
val str3 = s"${str1}defg"
str3
}
println(str3) --訪問不到
scala中語句塊的最後一句,就是該語句塊的返回值

8.if...else...
scala中的if else語法是有返回值的,因此可以在變量的賦值上就使用if else語法
另外scala中沒有三目運算表達式
9.while循環
語句塊中是沒有返回值的

10.for循環
for也是scala中少數沒有返回值的語句塊之一
但是scala中也提供了一種方式(yield)讓其具有返回值的能力
java for
for(int i=0;i<10;i++){}
scala 的for 更像 foreach
for(String i:slist){}
for(i <- list){}

通過守衛來限定判斷條件
for(i <- 1 to times if i%2==0) println(s"2print:$i")

scala裏麵沒有break 也沒有continue
1.但是可以使用scala中提供的特殊類型Breaks來實現break
2.通過return 終止整個函數的方式也可以終結循環

11.Unit類型
java裏無返回值的方法類型是void
scala中沒有void,它使用Unit類型來代替
Unit的實例就是“()”

12 函數定義
函數定義和對象的定義一樣,編譯器可以通過返回值來自動判斷返回值
因此,絕大多數的函數定義,都不寫返回值類型
隻有一種情況例外:遞歸函數
def functionName(x:Int,y:Int):Int = {
x+y
}
在scala因為函數是對象,因此它的定義方式有很多

下麵的這個函數定義是一個過程函數的定義,過程函數是沒有返回值的,即返回值是Unit
隻要函數這麼定義它的返回值就是Unit,就算在函數體內return也不會返回結果
def functionName(x:Int,y:Int){
x+y
}
如果定義函數時把函數的類型指定為Unit那麼不管該函數的語句塊最後一句結果是什麼,
該函數的返回值始終是Unit()
13 函數類型
因為scala中函數是一等公民,因此它和對象一樣也有自己的類型
因為函數中涉及的類型包括參數的類型,返回值類型,因此函數的類型就用參數類型和返回值類型來共同定義
如:
def plusInt(x:Int,y:Int)={
x+y
}
那麼該函數有兩個參數都是Int,有一個返回值也是Int,那麼在scala中的函數類型描述是:
(Int,Int)=>Int
其中 => 符號分割參數定義(輸入)類型 和 返回值(輸出)的類型
(Int)=>Int
Int =>Int
(Int,Int)=>Int

14 函數字麵量(匿名函數)
函數的字麵量也是用=>來進行定義,它左邊是參數(輸入),右邊是返回值(輸出)
val plusIntVal:(Int,Int)=>Int = (x,y)=>x+y
val plusIntVal1 = (x:Int,y:Int)=>x+y

15 def定義的函數不可以被當做對象來被傳遞
val定義的函數可以被當做函數來被傳遞
val定義的函數名稱,後麵不加小括號代表的是對函數對象的引用,後麵添加小括號代表的是對函數的調用

16 Array是可變(元素可變)的,它和java的數組T[]是對應的
數組是定長的,定義的時候必須指定長度,一旦聲明長度不可發生變化

17 ArrayBuffer是變長數組,該類型對象在聲明定義時可以不用指定長度,隨著程序的運行
可以隨意增間該對象的元素

18 List是不可變的元素列表,裏麵的元素不可更改,長度也不可更改
List具有遞歸結構(Recursive Structure)和其它類型集合一樣,它具有協變性
比方說Student 是 Person的子類
List[Studnt] 也是 List[Person]的子類
<? extends Person>

19 val def lazy定義變量的區別

20 scala的類定義也是使用class關鍵詞後麵跟類的名稱然後大括號
class Person {}
Java類體內:
屬性
靜態屬性
非靜態屬性
方法 靜態方法
非靜態方法

          靜態代碼塊 :類被加載時執行

scala類體內:
屬性:非靜態屬性
方法:非靜態方法
非靜態代碼塊 :每一次被實例化的時候都會被執行一次
(class裏麵的過程代碼(代碼塊),其實就是類的構造方法)

scala中沒有static關鍵詞
scala中用Object(單例類)來承擔靜態的成員定義

在Class定義的屬性和方法必須要通過實例化的對象才能調用
在Object裏麵定義的屬性和方法,直接用Object名稱就可以調用

scala的成員也可以使用
private 和protected修飾但是沒有public

----跟java一致的部分
沒有(public):所有其他代碼都可以訪問
private:隻有自己可以訪問
protected:隻有子類和同包下麵的可以訪問
----跟java一致的部分
private:隻有自己可以訪問
除了自己可以訪問之外可以額外開放訪問權限
protected:隻有子類和同包下麵的可以訪問
除了子類和同包外也可以額外開放訪問權限
21 構造方法
Java構造方法:有默認無參構造方法
自定義構造方法時默認構造方法消失
構造方法可以重載 [public 類名(參數列表){}]
不同的構造方法之間地位是平等的
Scala構造方法:有無參的默認構造方法
構造方法也可以重載
不同構造方法之間地位不平等,每個scala類都隻有一個唯一的主構造方法
除了主構造方法之外,所有次構造方法體內都必須直接或間接的調用主構造方法來完成對象的構建
主構造方法的聲明是類聲明後麵來寫
次構造方法是寫在類體內的,它的名字統一都叫this
所有的次構造方法在方法體內必須先間接或直接的調用主構造方法後才能寫自己的構造邏輯代碼,構造方法不需要返回值,它返回值是Unit

              構造方法可以使用默認值參數
              class ConstructorWithDefault(var attr1:String,var attr2:String = "defaultATTR2",var attr3:Int = 3)
              這樣能大大提高構造方法調用的靈活性
              可以通過在主構造方法參數前麵加private的方式來講主構造方法私有化
              class ConstructorMainPrivate private(var attr1:String,var attr2:String)

22 單例對象object
單例對象的屬性和方法,可以直接通過單例對象的名稱來調用,不需要實例化,它本身就是一個對象
23 如果定義一個object和一個class 他們的名稱一樣如Student,那麼在編譯成class文件的時候
他們的會共用一個Student.class的文件
這樣一個object和class他們互為伴生
在伴生類中可以通過類名調用伴生對象的屬性和方法
但是伴生對象不可以調用伴生類的屬性和方法

伴生類和伴生對象之間可以相互訪問private的成員
但是如果private添加泛型限定則會有額外的限製,如private[this]

24 apply方法在scala中是有特殊作用的方法,它可以直接通過object名稱後麵加小括號的形式來調用
object Student 在其中定義一個apply方法

Student.apply() ====(等用於) Student()
apply方法和普通方法一樣可以被重載

25 抽象類
java抽象類: 不能夠被實例化
可以定義屬性,可以定義已實現的方法,也可以定義抽象方法
子類必須實現抽象類中所有的抽象方法
scala抽象類:不能夠被實例化
可以定義屬性,可以定義已實現的方法
可以定義未被初始化的屬性,和未被實現的方法
子類必須初始化所有抽象類中未初始化的屬性
必須實現抽象類中未被實現的方法
在定義未實現的方法上必須指定返回值類型

            抽象類可以定義構造方法,構造方法上也可以通過var val等修飾符聲明屬性
            抽象類主構造方法上有屬性定義,子類在繼承時必須給抽象類的構造方法傳值

            在子類被實例化的時候會先調用父類的構造方法再調用子類的構造方法

26 繼承
scala中的繼承和java一樣使用extends修飾符來定義父類和子類之間的關係
子類會從父類中繼承訪問控製權限內的屬性和方法
子類重寫父類方法的時候,如果父類是抽象類,重寫的方法是抽象方法override關鍵詞可以省略
否則必須寫override

27 匿名類
當我們想要實例化一個類型的對象的時候,如果這個類型是一個抽象類,或者是一個接口
而我們又不想重新定義一個類型來繼承抽象類或實現接口
這時候我們可以使用匿名類
可以使用
new AbstractType(){
//實現或重寫父類的方法
}
28 組合和繼承
當我們想定義一個類型,並且希望這個類型具有比較強大的功能的時候
我們可以考慮兩種方式:1 繼承 操作簡單
在功能使用上麵,直接調用可訪問的屬性和方法(不需要實例化父類的對象)

                             繼承隻能單繼承
                             繼承侵入性太強,沒辦法解耦
                     2 聚合  操作複雜 會額外寫很多代碼,比方說接口的定義
                             對功能方法的調用需要通過實例對象來進行

                             可以多方引入,沒有單繼承出現的問題
                             方便解耦,使用接口來引入想要擴展的類型

29 scala的總父類型是Any
AnyVal相當於java的基礎數據類型
AnyRef相當於java中的Object
30 java的接口:interface
常量
未實現的方法
scala的接口:traits
常量
未實現的方法

                     變量 初始化的變量和未初始化的變量
                     已實現的方法

兩種語言在定義接口實現類的時候都必須實現全部接口未實現的方法(scala中包含未初始化的變量)

traits可以多實現 而抽象類隻能繼承一個

trait不可以被實例化

如果一個類要實現多個接口的話,第一個接口前用extends,後麵每一個接口前都用with
class ImpClass extends Trait1 with Trait2 with Trait3...
如果一個類既要繼承另一個類又要實現多個接口,那麼被繼承的類寫在extends後麵,所有的接口前麵加with
class ExtendedAndImpClass extends SuperClass with Trait1 with Trait2 ...

trait之間也可以繼承,可以被多繼承

31 包和引入
scala中引入包(import)的基本用法和java一致,除了導入包下所有類型的時候Java用的是*,scala中用的是_
scala中可以在引入統一個包的時候用一行代碼引入多個類型
import java.util.{Date,Random}

scala中可以在任意的地方引入包
在代碼塊裏用import引入包它的作用域就是代碼塊內
如果在scala文件的最上方引入,那麼它在整個文件內都生效

scala中引入的類型的時候可以給類型起別名
import scala.collection.mutable.{Queue=>MutableQueue}

scala還可以使用import的方式類隱藏類型
import scala.collection.immutable.{HashMap=>,}
相當於在當前引入的所有immutable下的類型隱藏HashMap
在使用HashMap的時候就不會發生類名衝突的問題

包的定義基本用法和java一致,同時也有更高級的用法
包的定義可以嵌套,可以和目錄不一致

32 包對象
包對象上經常用來定義一個包下可以使用的常量,函數,object等
在使用這些函數和常量時可以無引用的調用,類似 println

一個包下麵隻能有一個包對象
定義方式:package object name...
包對象所定義的包下的類可以無引用的使用包對象中的屬性和方法

包對象定義的包外的類也可以無引用的使用包對象中的屬性和方法,但是需要使用import來導入
import com.zhiyou.bd17.oo.packagetest._

33 權限訪問控製和包的關係
private或protected是scala中僅有的兩個權限控製修飾

private後麵可以通過添加中括號的方式來更靈活的進行自己的權限控製
中括號中可以寫:
1.伴生對象伴生類可以各自訪問私有成員
2.內部類
private[this] -- 限製上述伴生對象訪問自己的私有成員
private[類名] --
private[包名] -- 擴充包下的類也可以訪問自己的私有成員

34 創建maven的scala項目
1.找模板(scala maven archetype) https://docs.scala-lang.org/tutorials/scala-with-maven.html
G:net.alchim31.maven
A:scala-archetype-simple
V:1.5
2.intellj中new--》project--》maven
勾選create from archetype
點擊 add archetype按鈕
模板下載完之後選擇我們添加的模板:net.alchim31.maven:scala-archetype-simple
next
3.填寫自己項目的GAV
4.next---next---finish
5.import changens
6.pom中修改
2.11.tools.version>
2.11.8.version>
改成自己的版本

刪除:


org.specs2
specs2_${scala.tools.version}
1.13
test


org.scalatest
scalatest_${scala.tools.version}
2.0.M6-SNAP8
test

刪除:

-make:transitive

刪除 test.scala.samples下的所有代碼

7.打開App程序 右鍵運行
打印結果
scala maven就創建成功

在pom中導入mysql驅動
用scala寫一個mysql的增刪改查

最後更新:2017-11-16 23:04:07

  上一篇:go  望雲棲
  下一篇:go  11月22日彈性計算跟您在廣州不見不散