1.面向對象java
Scala的類與java、C++的一些比起來更簡潔,速度更快app
對象:使用object關鍵字修飾的函數
類:使用class關鍵字修飾的new Person()實例對象this
new類:類的實例(對象)spa
1.1.單例對象scala
(1)scala中沒有靜態方法和靜態字段,沒有staticcode
(2) java中,沒有關鍵字修飾的方法,只能用new class()來修飾方法對象
(3)隊友一個class來講,全部的方法和成員變量在市裏被new出來以前都沒法訪問blog
(4)雖然在class中的定義main方法,但是並無什麼用,按時能夠用object達到一樣的目的繼承
(5)用object修飾的對象是單例的,成爲單例對象,靜態對象
(6)單例模式涉及到一個單一的類,該類負責建立本身的對象,同時確保只有單個對象被建立,這個類提供了一種訪問其惟一對象的方式,能夠直接訪問,不須要實例化該類的對象。注意:1.單例類只能有一個實例 2.單例類必須本身按建立本身的惟一實例 3.單例類必須給其餘對象提供這一實例
代碼:
object SIngeDemo { var name="娜娜" def eat():Unit={ println(name+"是吃貨!") } } object test{ def main(args: Array[String]): Unit = { SIngeDemo.eat() } }
1,2.伴生對象
伴生對象是一種特殊的單例對象,是一種相對概念,須要兩個條件:
條件1:在同一個源文件中
條件2:對象名和類名相同
這樣的單例對象,被稱爲這個類的伴生對象。類被稱爲這個實例的單例對象的伴生類。
特色:類和伴生對象之間能夠相互訪問私有的方法和屬性
代碼:
class AssociatedDemo { private val name="笑笑" private def eat():Unit={ println(name+"是吃貨!") println(name+"喜歡"+AssociatedDemo.action) } } object AssociatedDemo{ private val name="娜娜" private val action="跑步" def main(args: Array[String]): Unit = { val associatedDemo = new AssociatedDemo associatedDemo.eat() } }
運行結果:
1.3.apply方法
(1)咱們一般會在伴生對象中定義apply方法,當遇到對象名(參數1,。。參數n)時apply方法會被調用
(2)當使用對象(參數列表)時,回去對象中找對應參數的apply方法,若是找到就執行相應的邏輯,若是找不到,就報錯
注意:只能找到和參數列表相對應的apply方法
該語法的目的:更方便的完成類或實例對象的初始化方法,賦值等工做,相似於java的方法重載
代碼:
//當scala中類或者對象有一個主要用途的時候,apply方法是一個湖人好的語法糖
class Test01(name:String) { } object Test01{ def apply(name: String): Test01 ={ new Test01 ( name ) } } //定義一個Test01類,而且在這個類中,有一個半生對象Test01,裏面定義了apply方法,有了這個apply方法之後,咱們在調用這個Test01類的時候,用函數方式來調用 object Client1{ def main(args: Array[String]): Unit = { val stu=Test01("娜娜") } }
總結:
(1)apply方法,是object上的方法
(2)通常狀況下,對象沒有構造方法,不能加參數
object Test1(name:String)寫法錯誤{
def main(args: Array[String]): Unit = {
Test1// 這是一個對象,對象上不能有參數
Test1(a:Int) // 添加參數以後,就報錯了(錯誤的寫法)
}
}
(3)可是,若是對象(參數列表),實際上調用的是對象上的apply方法,具體會根據參數列表的個數、參數的類型去找對象上對應的apply方法,若是沒有找到就會報錯。返回值取決於apply的返回類型
(4)apply方法至關於java中的方法重載,能夠定義多個apply方法,具體的參數類型,參數個數,以及返回值都是能夠自定義。
1.4.unapply方法
unapply方法是接受一個對象,從對象中提取相應的值。主要用於模式匹配
代碼:
class Money(val price:Double,val name:String) { } object Money{ def apply(price: Double, name: String): Money = new Money ( price, name ) def unapply(money: Money): Option[(Double, String)] = { if (money==null){ None }else{ Some(money.price,money.name) } } } object Client2{ def main(args: Array[String]): Unit = { val ap=Money(11.2,"書") ap match { case Money(num,"書")=>println(num) case _=>println("寶寶不開心!") } } }
結果:
1.5.應用程序對象
scala程序都必須從一個對象的main方法開始,能夠經過繼承APP特質,不用寫main方法(APP裏面封裝了main方法)
object AppDemo extends App{ println("I love you ") }
2.類
2.1.類的定義
(1)在 scala中,類並不用生命爲public
(2) scala源文件中能夠包含多各種,全部的類都具備可見性
(3)var修飾的變量,這個變量對外提供了get set方法
(4)val修飾的變量,是隻讀屬性,對外提供了get方法,沒有set方法(至關於java中的final變量)
2.2.構造器
scala構造器分爲兩類:主構造器(只能有一個),輔助構造器(能夠有多個)
(1)主構造器直接在類名後面定義,每一個類都有主構造器,主構造器的參數直接放置雷鳴後面,與類交織在一塊兒
class test(val name:String,var age:Int)
(2)若是沒有定義構造器,類會有一個默認的空參構造器
(3)輔助函數的定義,使用dfs this關鍵字,並且必須調用主構造器,或者其餘構造器
注意:主構造器會執行類定義中的全部語句
代碼:
class ConstructorDemo(val name: String, var age: Int) { println ( "主構造器運行了。。。" ) //輔助構造器必須定義在類中(主和輔參數不能同樣) def this(name: String, age: Int, sex: String) { this ( name, age ) println ( "第一個輔助構造器運行了。。。。" ) } def this(name: String, age: Int, sex: String, address: String) { this ( name, age, sex ) println ( "第二個輔助構造器運行了。。。。" ) } } object Text { def main(args: Array[String]): Unit = { new ConstructorDemo ( "娜娜", 20 ) new ConstructorDemo ( "娜娜", 20, "女" ) new ConstructorDemo ( "娜娜", 20, "女", "河南" ) } }
總結:
1.有兩類構造器,主構造器和付構造器
2.構造器定義的位置,主構造器和類交織在一塊兒,class ConstructorDemo(val name: String, var age: Int)
3.輔助構造器是一個特殊的方法,定義在類中 def this(name: String, age: Int, sex: String, address: String)
4.輔助構造器,第一行必須是主構造器(或者其餘構造器)
5.輔助構造器的參數不能和主構造器的參數徹底一致(參數個數、類型、順序)
6.能夠定義空參的輔助構造器,可是主構造器參數必須進行初始化賦值
7.做用域:輔助構造器的做用於,只在方法中,主構造的做用因而類中除去成員屬性和成員方法以外的全部範圍(能夠經過反編譯查看源碼)
2.3.訪問權限
成員變量的訪問權限
1.默認權限是public,任何地方均可以訪問
2.prive做用域(用於類的內部和伴生對象中)
3.private[this],做用域在當前類中,伴生對象無效
方法的訪問權限
1.通用於主構造器,輔助構造器,以及普通方法
2.默認權限是共有的
3.private做用域爲類和其伴生對象
4. private [this] ,做用域爲當前類中,伴生對象中無效
類的訪問權限:
1.默認: 共有的
2. private private[this] 在當前包及其子包範圍內有效,其餘地方無效
3. private [包名] 在指定包及其子包訪問內有效 其餘地方無效