scala学习-类与对象
?類 / 對(duì)象
【《快學(xué)Scala》筆記】
一、類
1、Scala中的類是公有可見性的,且多個(gè)類可以包含在同一個(gè)源文件中;
1 class Counter{ 2 private var value = 0 //類成員變量必須初始化,否則報(bào)錯(cuò) 3 4 def increment(){ //類中的方法默認(rèn)是公有可見性 5 value += 1 6 } 7 8 def current() = value //對(duì)于類中的“取值方法”,在定義時(shí)可省略掉括號(hào),直接 def current = value 9 }Scala類的使用:
Scala的類在未提供構(gòu)造器時(shí),也會(huì)提供默認(rèn)構(gòu)造器;且在調(diào)用無(wú)參構(gòu)造器或無(wú)參方法時(shí)可省略掉方法后的括號(hào)。
2、Scala類的每個(gè)字段都有g(shù)etter和setter方法,私有字段的getter和setter默認(rèn)是私有的,公有字段的getter和setter方法默認(rèn)是公有的。
其中對(duì)于類中的屬性value,Scala類默認(rèn)生成的getter方法名為 value,默認(rèn)生成的setter方法名為 value_=?。使用時(shí),我們可以重新定義獲取或設(shè)置屬性的方法。
例如,
1 class Clock{ 2 var hour = 0 3 var minute = 0 4 var second = 0 5 6 def getTime():String={ 7 return hour+":"+minute+":"+second 8 } 9 }對(duì)于Clock類中的屬性,如 hour,其對(duì)應(yīng)的getter方法為 hour ,其對(duì)應(yīng)的setter方法名為 hour_=?
【注:可以重新定義獲取Scala類中屬性的方法,但是最好不要與屬性默認(rèn)對(duì)應(yīng)的getter/setter方法重名,否則會(huì)報(bào)錯(cuò)。】
3、對(duì)于Scala類中的val屬性,只有默認(rèn)的getter方法;對(duì)于private屬性,其默認(rèn)getter、setter都是private的。因而,對(duì)于不想提供setter方法的變量可以設(shè)置為val,對(duì)于不想提供getter、setter方法的變量可以設(shè)置為private。
4、注意,Scala類中,定義無(wú)參函數(shù)時(shí),若函數(shù)聲明時(shí)省略了函數(shù)名后的括號(hào)(由于無(wú)參數(shù),可以省略),調(diào)用時(shí),必須參數(shù)無(wú)括號(hào)的形式,通過帶括號(hào)形式調(diào)用會(huì)報(bào)錯(cuò)。如,
1 class Counter{ 2 var value = 0 3 4 def current = value 5 }類Counter定義中,對(duì)于方法current,由于不接受參數(shù),所以定義時(shí)省略了方法名current后的括號(hào)。此時(shí),對(duì)于Counter的實(shí)例counter,調(diào)用current方法時(shí),必須采用counter.current(無(wú)括號(hào)形式)。
5、對(duì)于Scala類中定義的字段,在Scala中實(shí)際為私有字段。(還有待進(jìn)一步理解和驗(yàn)證)
1 class Counter{ 2 var value = 0 3 val sum = 0 4 private var cnt = 1 5 6 //.... 7 }在Counter類中,Scala在為Counter生成面向JVM的類時(shí),對(duì)于value字段,會(huì)生成對(duì)應(yīng)的私有字段value和公有的getter、setter方法;對(duì)于sum字段,會(huì)生成私有的final字段和公有的getter方法;對(duì)于cnt字段,會(huì)生成私有字段cnt和私有的getter、setter方法(貌似這個(gè)private聲明只是影響的Scala根據(jù)屬性生成的對(duì)應(yīng)getter、setter的可見性)。
6、構(gòu)造器
Scala的類可以有一個(gè)主構(gòu)造器和多個(gè)輔助構(gòu)造器。每個(gè)輔助構(gòu)造器的名稱為this,每一個(gè)輔助構(gòu)造器都必須以調(diào)用已經(jīng)定義的輔助構(gòu)造器或主構(gòu)造器開始定義。
- 主構(gòu)造器
如果一個(gè)類沒有顯示定義主構(gòu)造器,則有一個(gè)默認(rèn)的無(wú)參主構(gòu)造器。
如定義一個(gè)Student類,
1 class Student(val name:String, var age:Int = 0, address:String = "", private var school:String = ""){ 2 var grade:Int = if( age>7 ) age-7 else 0 3 4 println(" I'm in main constructor. ") 5 6 def info() = " name is "+name+", age is "+age+", address is "+address 7 }? 對(duì)于Scala類,主構(gòu)造器的參數(shù)放置在類名后,由括號(hào)括起來(lái)。且對(duì)于主構(gòu)造器中var、val、private 等標(biāo)注的參數(shù),都會(huì)成為類的對(duì)應(yīng)字段,并生成對(duì)應(yīng)的默認(rèn)getter、setter方法。如Student類中的name、age、school等。對(duì)于主構(gòu)造器中的未用var、val標(biāo)注的參數(shù),如果在類的任何一個(gè)方法用用到該參數(shù),該參數(shù)將會(huì)轉(zhuǎn)換為類的字段,否則不會(huì),如Student類的address屬性。
由于在Student類中的info方法中用到了參數(shù)address,所以Student共有name、age、address、school、grade等5個(gè)屬性,且Scala根據(jù)對(duì)應(yīng)屬性的特點(diǎn)生成了默認(rèn)的getter和setter方法。
對(duì)于主構(gòu)造器的參數(shù),也可以提供參數(shù)默認(rèn)值。通過為主構(gòu)造器提供默認(rèn)值可減少輔助構(gòu)造器的個(gè)數(shù)。
主構(gòu)造器的函數(shù)體,是類中除了方法定義以外的其他語(yǔ)句,如在Student類的主構(gòu)造器中,包含grade屬性的初始化和prinln這兩行語(yǔ)句。
Stuent類的使用。
- 輔助構(gòu)造器
輔助構(gòu)造器通過this來(lái)定義,且必須首先調(diào)用主構(gòu)造器或者其他已經(jīng)定義的輔助構(gòu)造器。
1 class Person(val name:String){ 2 var age = 0 3 var sex:Char = 'f' 4 5 println("main constructor...") 6 7 def this(name:String, age:Int){ 8 this(name) //調(diào)用主構(gòu)造器 9 this.age = age //使用this關(guān)鍵字 10 11 println(" auxiliary constructor1 ") 12 } 13 14 def this(name:String, age:Int, sex:Char){ 15 this(name, age) 16 17 this.sex = sex 18 19 println(" auxiliary constructor2 ") 20 } 21 }【注:輔助構(gòu)造器的參數(shù)前不能添加val、var標(biāo)志,否則會(huì)報(bào)錯(cuò)。】
- 私有主構(gòu)造器
私有構(gòu)造器通過在類名后用private關(guān)鍵字標(biāo)注主構(gòu)造器參數(shù)來(lái)標(biāo)明。此時(shí),可以通過輔助構(gòu)造器來(lái)創(chuàng)建該類的對(duì)象。
7、嵌套類
1 class Family(val h_name:String, val w_name:String){ 2 class Husband(var name:String){ 3 println(" I'm a husband ") 4 } 5 6 class Wife(var name:String){ 7 println(" I'm a Wife ") 8 } 9 10 var husband = new Husband(h_name) 11 var wife = new Wife(w_name) 12 13 def info(){ 14 println( "husband: "+husband.name+", wife:"+wife.name ) 15 } 16 }在Scala中,你幾乎可以在任何語(yǔ)法結(jié)構(gòu)中嵌套任何語(yǔ)法結(jié)構(gòu),如在函數(shù)中定義函數(shù),在類中定義類。
?二、對(duì)象(object)
1、Scala中沒有靜態(tài)方法和靜態(tài)字段,但是可以用object語(yǔ)法來(lái)實(shí)現(xiàn)類似的功能。對(duì)象定義了某個(gè)類的單個(gè)實(shí)例。
Scala的object中可以用來(lái)實(shí)現(xiàn)類似的功能,用來(lái)存放工具函數(shù)或常量等。如,
1 object Sequence{ 2 private var next_num = 0 3 val threshold = 100 4 5 def getSequence() = { 6 next_num += 1 7 next_num 8 } 9 }使用object中的常量或方法,通過object名直接調(diào)用,對(duì)象構(gòu)造器在對(duì)象第一次被使用時(shí)調(diào)用(如果某對(duì)象一直未被使用,那么其構(gòu)造器也不會(huì)被調(diào)用)。
object的構(gòu)造器不接受參數(shù)傳遞。
2、伴生對(duì)象
可以將在Java類中定義的靜態(tài)常量、方法等放置到Scala的類的伴生對(duì)象中。伴生對(duì)象與類同名,且必須放置在同一源文件中。類可以訪問伴生對(duì)象私有特性,但是必須通過 伴生對(duì)象.屬性名 或 伴生對(duì)象.方法 調(diào)用。
伴生對(duì)象是類的一個(gè)特殊實(shí)例。
1 class Counter{ 2 def getTotalCounter()= Counter.getCount 3 } 4 5 object Counter{ 6 private var cnt = 0 7 8 private def getCount()= cnt 9 }如在類Counter訪問其伴生對(duì)象的石油方法getCount,必須通過 Counter.getCount() 的方式調(diào)用。
3、對(duì)象可以繼承或擴(kuò)展多個(gè)特質(zhì)
1 abstract class Person(var name:String, var age:Int){ 2 def info():Unit 3 } 4 5 object XiaoMing extends Person("XiaoMing", 5){ 6 def info(){ 7 println(" name is "+name+", age is "+age) 8 } 9 }?
4、apply方法
當(dāng)遇到 object(參數(shù)1, 參數(shù)2,....,參數(shù)n)的形式的調(diào)用時(shí),apply方法便會(huì)被調(diào)用。
5、main方法——Scala程序的入口
main方法定義在object中,形式如下:
1 object HelloWorld{ 2 def main(args: Array[String]){ 3 println("Hello World!") 4 } 5 }?
可以通過scalac 源文件名,然后通過 scala 類名 來(lái)執(zhí)行主程序。
6、還可以通過擴(kuò)展特質(zhì)App來(lái)運(yùn)行指定代碼
1 object HelloWorld2 extends App{ 2 println(" A 'Hello world' from HelloWorld2 ") 3 }?
通過擴(kuò)展App特質(zhì)的方式執(zhí)行程序時(shí),將要執(zhí)行的程序放到了object的主構(gòu)造器中。
7、枚舉
Scala并沒有定義枚舉類型,但是可以通過定義擴(kuò)展Enumeration的對(duì)象,并用Value方法初始化枚舉類中的所有可選值,提供枚舉。
1 object TrafficeLight extends Enumeration{ 2 val Red, Yellow, Green = Value 3 4 }?
上述實(shí)例中的val Red, Yellow, Green = Value語(yǔ)句,相當(dāng)于
1 val Red = Value 2 val Yellow = Value 3 val Green = Value用Value方法初始化枚舉類變量時(shí),Value方法會(huì)返回內(nèi)部類的新實(shí)例,且該內(nèi)部類也叫Value。另外,在調(diào)用Value方法時(shí),也可傳入ID、名稱兩參數(shù)。如果未指定ID,默認(rèn)從零開始,后面參數(shù)的ID是前一參數(shù)ID值加1。如果未指定名稱,默認(rèn)與屬性字段同名。
1 object TrafficLight extends Enumeration{ 2 val Red = Value(1, "Stop") 3 val Yellow = Value("Wait") //可以單獨(dú)傳名稱 4 val Green = Value(4) //可以單獨(dú)傳ID 5 }?
上例中,Yellow屬性就僅定義了名稱,Green僅定義ID。
參數(shù)在不指定名稱時(shí),默認(rèn)參數(shù)的Value為字段名。
【注:枚舉類型的值是, 對(duì)象名.Value ,如上例中的枚舉類型是 TrafficLight.Value。】
8、通過id方法獲取枚舉類型值的ID
9、通過values方法獲取所有枚舉值的集合
10、通過ID來(lái)獲取對(duì)應(yīng)的枚舉對(duì)象
?
轉(zhuǎn)載于:https://www.cnblogs.com/-crazysnail/p/3984010.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的scala学习-类与对象的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hihocoder1089 Floyd算
- 下一篇: cesium-加载点云数据