版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
12.Scala面向?qū)ο缶幊桃?、類和對象二、操作符即方法三、類繼承四、特質(zhì)目錄2一、類和對象3面向過程編程類和對象面向?qū)ο缶幊淌裁词敲嫦驅(qū)ο缶幊??萬物皆對象!醫(yī)囑、護(hù)士、病人、手、皮膚、血管、消毒水、空氣……4面向過程編程類和對象面向?qū)ο缶幊淌裁词敲嫦驅(qū)ο缶幊蹋啃枨螅喊汛笙笮∨盅b進(jìn)冰箱小冰void小冰開門(){}void小胖進(jìn)小冰(){}void小冰關(guān)門(){}Intmain(){
小冰開門();小胖進(jìn)小冰();小冰關(guān)門();}class冰箱{def開門(){}def關(guān)門(){}}class大象{def進(jìn)入(d:String){}}object大象進(jìn)冰箱{defmain(args:Array[String]):Unit={val小胖=new大象val小冰=new冰箱
小冰.開門
小胖.進(jìn)入(小冰)小冰.關(guān)門}}5為什么選面向?qū)ο缶幊??面向過程編程ProcedureOriented
一、類和對象面向?qū)ο缶幊?/p>
ObjectOriented
///jerry11112/article/details/79027834易維護(hù)、易復(fù)用、易擴(kuò)展一些情景下性能比面向?qū)ο蟾?類:一個(gè)模板,它描述一類對象的行為和狀態(tài)。對象:類的一個(gè)實(shí)例,具體的事物。類是創(chuàng)建對象的模板,對象是類的實(shí)例
一、類和對象1.1類??類:狗狀態(tài):顏色,名字,品種行為:吃,叫,搖尾巴對象2顏色:黑白名字:二毛品種:哈士奇類與對象的概念對象1顏色:黃白名字:大旺品種:中華田園7類里有什么?一、類和對象??類:狗字段:顏色,名字,品種方法:吃,叫,搖尾巴1.1類方法:用“def”定義的函數(shù),是對象具有的行為成員構(gòu)造對象時(shí),操作系統(tǒng)會分配存儲給每個(gè)對象來放自己的字段,但不需要為某個(gè)對象單獨(dú)保存其方法!字段:val或var類型的變量,保存對象的狀態(tài)或數(shù)據(jù)8例如:一、類和對象[修飾符]
class類名{
類體}1.1類一般不加,省略時(shí)是默認(rèn)類具有公有可見的classStudents{
varname="None"
varage:Int=_
varscore:Double=_
defregister(n:String,a:Int,sc:Double):Unit={
name=n
age=a
score=sc
}
}定義類Students申明字段,必須顯示的初始化定義方法register定義類9一、類和對象創(chuàng)建對象說明:val類型的變量只能與初始化時(shí)的對象綁定,不能再被賦予新的對象。Scala
在創(chuàng)建對象時(shí),類型聲明可以省略。一般一個(gè)對象的類型,就是這個(gè)類。val對象名[:類型]=new
類名()1.1類10一、類和對象訪問對象成員對象名.字段名1.1類對象名.方法名scala>classStudents{
|privatevarname="None"
|defregister(n:String)=name=n
|defdisplay()=println(name)
|}
definedclassStudents
scala>valstu=newStudents
stu:Students=Students@15a7e51
scala>stu.register("Bob")
scala>
^
error:variablenameinclassStudentscannotbeaccessedinStudents
scala>stu.display()
Bob只可訪問公有的類成員(默認(rèn)公有),外部不可訪問private修飾的類成員創(chuàng)建對象并賦給變量stu調(diào)用方法register外部訪問字段name11一、類和對象1.2類的構(gòu)造方法主構(gòu)造方法不需要顯式定義
,類內(nèi)部非字段、非方法的代碼都是“主構(gòu)造方法”。類名后面可以定義若干個(gè)參數(shù)列表,用于接收參數(shù),參數(shù)將在構(gòu)造對象時(shí)用于初始化字段并傳遞給主構(gòu)造方法使用。需求:如果想在創(chuàng)建Sutdents的對象時(shí)直接指定這個(gè)對象的姓名,該怎么做?
是一種特殊的方法,用于完成對新對象的初始化。構(gòu)造方法類的構(gòu)造方法主構(gòu)造方法輔助構(gòu)造方法12一、類和對象舉例:1.2類的構(gòu)造方法scala>classStudents(n:String){
|valname=n
|println("Astudentnamed"+n+"hasbeenregistered.")
|}
definedclassStudents
scala>valstu=newStudents("Tom")
AstudentnamedTomhasbeenregistered.
stu:Students=Students@5464eb28主構(gòu)造方法Students類接收一個(gè)String參數(shù)n,并用n來初始化字段name主構(gòu)造方法構(gòu)造對象時(shí)初始化字段name并調(diào)用主構(gòu)造方法13一、類和對象1.2類的構(gòu)造方法輔助構(gòu)造方法目的:任何構(gòu)造方法最終都調(diào)用該類的主構(gòu)造方法,使主構(gòu)造方法成為類的單一入口。以“defthis(......)”來開頭;一個(gè)類內(nèi)可以有多個(gè)輔助構(gòu)造方法,編譯器通過不同參數(shù)來區(qū)分不同的輔助構(gòu)造方法。第一步行為必須是調(diào)用該類的主構(gòu)造方法或其它的輔助構(gòu)造方法。字段或方法“當(dāng)前”所在的對象14一、類和對象舉例:以“defthis(......)”開頭構(gòu)造方法通過參數(shù)區(qū)分第一步調(diào)用主構(gòu)造方法或另一個(gè)輔助構(gòu)造方法請同學(xué)們思考在構(gòu)造stu這個(gè)對象時(shí)是調(diào)用了哪個(gè)構(gòu)造方法呢?scala>classStudents(n:String){
|valname=n
|defthis()=this("None")
|println("Astudentnamed"+n+"hasbeenregistered.")
|}
definedclassStudents
scala>valstu=newStudents
AstudentnamedNonehasbeenregistered.
stu:Students=Students@1cf39c6調(diào)用主構(gòu)造方法輔助構(gòu)造方法1.2類的構(gòu)造方法輔助構(gòu)造方法15一、類和對象舉例:在類名與類的參數(shù)列表之間加上關(guān)鍵字“private”,那么主構(gòu)造方法就是私有的。scala>classStudentsprivate(n:String,m:Int){
|valname=n
|valscore=m
|defthis(n:String)=this(n,100)
|println(n+"'sscoreis"+m)
|}
definedclassStudents
scala>valstu=newStudents("Bill",90)
^
error:toomanyarguments(2)forconstructorStudents:(n:String)Students
scala>valstu=newStudents("Bill")Bill'sscoreis100
stu:Students=Students@4c3ed51.2類的構(gòu)造方法私有主構(gòu)造方法外部代碼構(gòu)造對象時(shí)不能通過主構(gòu)造方法進(jìn)行,而必須使用其他公有的輔助構(gòu)造方法或工廠方法(專門用于構(gòu)造對象的方法)16一、類和對象1.3類參數(shù)類參數(shù)也是主構(gòu)造方法的形參無修飾符修飾:僅僅是參數(shù),一個(gè)局部變量。val或var修飾:在類的內(nèi)部會生成一個(gè)與參數(shù)同名的公有字段,
構(gòu)造對象時(shí),這些參數(shù)會直接復(fù)制給同名字段。classPerson(valsex:String){
}sex不僅僅是參數(shù)還是類的公有字段,相當(dāng)于在類內(nèi)定義了valsex,其值可以在構(gòu)造對象時(shí)被傳入17一、類和對象1.3類參數(shù)舉例:scala>classStudents(valname:String,varscore:Int){
|defexam(s:Int)=score=s
|overridedeftoString=name+"'sscoreis"+score+"."
|}
definedclassStudents
scala>valstu=newStudents("Tim",90)
stu:Students=Tim'sscoreis90.
scala>stu.exam(100)
scala>stu.score
res0:Int=100不僅為類參數(shù),還是類成員可以在外部通過對象訪問18一、類和對象1.4方法重載方法重載:在類里定義了多個(gè)同名的方法,但是每個(gè)方法的參數(shù)不一樣。這些方法雖然同名,但是它們是不同的。方法重載是面向?qū)ο罄锒鄳B(tài)屬性的一種表現(xiàn)。classAdder{
defadd(a:Int,b:Int){
varsum=a+b
println(sum)
}
defadd(a:Int,b:Int,c:Int){
varsum=a+b+c
println(sum)
}
}在Adder類中有兩個(gè)版本的add方法19一、類和對象1.5單例對象與伴生對象單例對象:用“object”開頭定義一個(gè)對象。伴生對象、伴生類:單例對象&同名類C++、Java等語言:類內(nèi)可以有靜態(tài)變量(不屬于某個(gè)對象,是所有對象共有的)Scala:純粹的面向?qū)ο髮傩?,無靜態(tài)操作的概念為什么會有單例對象?存放靜態(tài)變量和方法作為程序的入口打包某方面功能的函數(shù)系列成為一個(gè)工具集伴生類和伴生對象必須在同一個(gè)文件里,兩者可以互訪對方的所有成員。單例對象的作用20一、類和對象1.6工廠對象與工廠方法工廠方法:專門用來構(gòu)造某一個(gè)類的對象的方法。工廠對象:包含這些工廠方法集合的單例對象。用法:工廠方法通常定義在伴生對象里。尤其是當(dāng)一系列類存在繼承關(guān)系時(shí),可以在基類的伴生對象里定義一系列對應(yīng)的工廠方法。作用:不用直接使用new來實(shí)例化對象,改用方法調(diào)用。對外隱藏了類的實(shí)現(xiàn)細(xì)節(jié)!21一、類和對象1.6工廠對象與工廠方法//students.scala
classStudents(valname:String,varscore:Int){
defexam(s:Int)=score=s
overridedeftoString=name+"'sscoreis"+score+"."
}
objectStudents{
defregisterStu(name:String,score:Int)=newStudents(name,score)
}將文件students.scala編譯后,在解釋器中可以這樣使用:scala>importStudents._
importStudents._
scala>valstu=registerStu("Tim",100)
valstu:Students=Tim'sscoreis100.導(dǎo)入單例對象調(diào)用工廠方法來構(gòu)造Students類的對象類Students的伴生對象,即工廠對象工廠方法22一、類和對象1.7apply方法用法:在伴生對象里定義名為apply的工廠方法,就能通過“伴生對象名(參數(shù))”來構(gòu)造一個(gè)對象。在類里定義一個(gè)與類相關(guān)的、具有特定行為的apply方法,讓使用者可以隱式調(diào)用,進(jìn)而隱藏相應(yīng)的實(shí)現(xiàn)細(xì)節(jié)。對象.apply(參數(shù))顯式調(diào)用對象(參數(shù))隱式調(diào)用如果apply是無參方法,必須寫出空括號!類和單例對象,都能定義apply方法23一、類和對象1.7apply方法//students2.scala
classStudents2(valname:String,varscore:Int){
defapply(s:Int)=score=s
defdisplay()=println("Currentscoreis"+score+".")
overridedeftoString=name+"'sscoreis"+score+"."
}
objectStudents2{
defapply(name:String,score:Int)=newStudents2(name,score)
}將文件students2.scala編譯后,就能在解釋器里這樣使用:scala>valstu2=Students2("Jack",60)
valstu2:Students2=Jack'sscoreis60.
scala>stu2(80)
scala>stu2.display()
Currentscoreis80.用伴生對象的工廠方法來構(gòu)造對象類中定義apply方法伴生對象中定義apply的工廠方法調(diào)用類中apply方法24一、類和對象1.8小結(jié)面向?qū)ο缶幊痰乃枷腩?、對象、方法、字段的概念和定義的語法類參數(shù)的概念、用類的構(gòu)造方法來構(gòu)造對象單例對象與伴生對象工廠對象與工廠方法apply方法25二、操作符即方法262.1操作符在Scala里的解釋基本類型:byte、short、int、char、float等操作符:+、-、*等二、操作符即方法C++、Java等“classByte”、“classShort”、“classChar”、“classInt”、“classLong”、“classFloat”、“classDouble”、“classBoolean”和“classUnit”九種值類定義在“classInt”、“classDouble”等類里的成員方法Scala追求純粹的面向?qū)ο?,萬物皆對象!抽象的、不可繼承的、對象由字面量表示272.1操作符在Scala里的解釋二、操作符即方法Int對象“1”調(diào)用了它的成員方法“+”,并把Int對象“2”當(dāng)作參數(shù)傳遞給了該方法,最后這個(gè)方法會返回一個(gè)新的Int對象“3”1+21.+(2)scala>classStudents3(valname:String,varscore:Int){
|defexam(s:Int)=score=s
|deffriends(n:String,s:Int)=println("Myfriend"+n+"gets"+s+".")
|overridedeftoString=name+"'sscoreis"+score+"."
|}
classStudents3
scala>valstu3=newStudents3("Alice",80)
valstu3:Students3=Alice'sscoreis80.
scala>stu3exam100
scala>stu3.score
valres0:Int=100
scala>stu3friends("Bob",70)
MyfriendBobgets70.方法調(diào)用都能寫成操作符的形式:去掉句點(diǎn)符號,并且方法參數(shù)只有一個(gè)時(shí)可以省略圓括號。28二、操作符即方法2.2三種操作符前綴操作符寫在操作數(shù)前面操作數(shù)只有一個(gè)一個(gè)無參方法,操作數(shù)是調(diào)用該方法的對象前綴操作符只有“+”、“-”、“!”和“~”四個(gè),相對應(yīng)的方法名分別是“unary_+”、“unary_-”、“unary_!”和“unary_~”;如果自定義的方法名是“unary_”加上這四個(gè)操作符之外的操作符,那么就不能寫成前綴操作符的形式。eg.定義了方法“unary_*”*p
p.unary_*
punary_*×√√29二、操作符即方法2.2三種操作符中綴操作符左右兩邊都接收操作數(shù)兩個(gè)操作數(shù)中的一個(gè)是調(diào)用該方法的對象,一個(gè)是傳入該方法的參數(shù)普通的有參方法參數(shù)那一邊沒有數(shù)量限制,只是多個(gè)參數(shù)需要放在圓括號里;以冒號“:”結(jié)尾的操作符,其右操作數(shù)是調(diào)用該方法的對象,其余操作符都是把左操作數(shù)當(dāng)調(diào)用該方法的對象。30二、操作符即方法2.2三種操作符后綴操作符寫在操作數(shù)后面的操作符并且操作數(shù)只有一個(gè),即調(diào)用該方法的對象無參方法方法名如果構(gòu)成前綴操作符的條件,那么既可以寫成前綴操作符,也可以把完整的方法名寫成后綴操作符。方法是“unary_+”、“unary_-”、“unary_!”和“unary_~”312.3操作符的優(yōu)先級和結(jié)合性二、操作符即方法優(yōu)先級通過方法名的首個(gè)字符來比較優(yōu)先級前綴操作符的方法名要去掉關(guān)鍵字圓括號內(nèi)的優(yōu)先級最高1+++2***31+++(2***3)322.3操作符的優(yōu)先級和結(jié)合性二、操作符即方法優(yōu)先級如果操作符以等號結(jié)尾,并且不是“>=”、“<=”、“==”或“!=”四個(gè)比較操作符之一,那么就認(rèn)為是賦值操作符,優(yōu)先級最低。sum*=1+2sum*=(1+2)例外“*=”的優(yōu)先級并不會因?yàn)橐浴?
”開頭就比“+”高,而是被當(dāng)作了一種賦值操作332.3操作符的優(yōu)先級和結(jié)合性二、操作符即方法結(jié)合性一般情況,同級的操作符:從左往右結(jié)合以冒號結(jié)尾的中綴操作符:從右往左結(jié)合a+b+c+d((a+b)+c)+da:::b:::c:::da:::(b:::(c:::d))例如:好的編程習(xí)慣:在操作符的結(jié)合順序不能一眼就看明白時(shí),最好加上圓括號來表示前后順序!342.4預(yù)設(shè)操作符二、操作符即方法+算術(shù)加法-算術(shù)減法*算術(shù)乘法/算術(shù)除法%算術(shù)取余>
大于<
小于>=大于等于<=小于等于==等于!=不等于&&、&邏輯與,前者短路,后者不短路||、|邏輯或,前者短路,后者不短路!邏輯非&位與|位或^位異或~位取反>>
算術(shù)右移<<
左移>>>
邏輯右移352.5對象的相等性二、操作符即方法自然相等性:字面上的值相等,就認(rèn)為兩個(gè)對象相等。引用相等性:構(gòu)造的對象常常會賦給一個(gè)變量,即讓變量引用該對象。引用相等性用于比較兩個(gè)變量是否引用了同一個(gè)對象。用“==”和“!=”比較用“eq”和“ne”比較思考:兩個(gè)變量引用了兩個(gè)完全一樣的對象,兩種相等性分別是什么?自然相等性:true引用相等性:false36二、操作符即方法舉例:2.5對象的相等性scala>vala=List(1,0,-1)
vala:List[Int]=List(1,0,-1)
scala>valb=List(1,0,-1)
valb:List[Int]=List(1,0,-1)
scala>valc=List(1,0,1)
valc:List[Int]=List(1,0,1)
scala>vald=a
vald:List[Int]=List(1,0,-1)scala>a==c
valres0:Boolean=false
scala>a==b
valres1:Boolean=true
scala>aeqb
valres3:Boolean=false
scala>aeqd
valres4:Boolean=true37二、操作符即方法2.6小結(jié)介紹了“操作符即方法”這個(gè)重要概念。熟悉了三種操作符的定義和使用學(xué)習(xí)了操作符的優(yōu)先級和結(jié)合性兩種對象相等性的判斷38三、類繼承393.1Scala的類繼承三、類繼承節(jié)省代碼量的兩種策略:包含和繼承。包含:
“hasa”一個(gè)類包括了另一個(gè)類的實(shí)例403.1Scala的類繼承三、類繼承節(jié)省代碼量的兩種策略:包含和繼承。繼承:
“isa”從一個(gè)寬泛的類可以派生出更加具體的類生物植物動物狗貓鴨超類超類子類子類413.1Scala的類繼承三、類繼承從一個(gè)寬泛的類可以派生出更加具體的類class子類名
extends
超類名
{
類體
}繼承的基本語法被繼承的類稱為“超類”,而派生出來的類稱為“子類”。如果繼承層次較深,最頂層的類通常也叫“基類”。超類的超類也叫超類,子類的子類還叫子類。子類可以繼承超類的字段和方法。423.1Scala的類繼承三、類繼承class子類名
extends
超類名
{
類體
}scala>classA{
|vala="ClassA"
|}
classA
scala>classBextendsA{
|valb="ClassBinheritsfromA"
|}
classB
scala>valx=newB
x:B=B@1919e19
scala>x.a
res0:String=ClassA
scala>x.b
res1:String=ClassBinheritsfromA定義子類B繼承自超類A433.2調(diào)用超類的構(gòu)造方法三、類繼承子類調(diào)用超類的構(gòu)造方法的語法class子類(子類對外接收的參數(shù))extends
超類(子類給超類的參數(shù))在構(gòu)造某個(gè)類的對象時(shí),如果這個(gè)類繼承自另外一個(gè)類,那么應(yīng)該先構(gòu)造超類對象的組件,再來構(gòu)造子類的其他組件。超類構(gòu)造方法繼承的構(gòu)造方法調(diào)用順序:子類構(gòu)造方法443.2調(diào)用超類的構(gòu)造方法三、類繼承超類構(gòu)造方法繼承的構(gòu)造方法調(diào)用順序:子類構(gòu)造方法scala>classA(vala:Int)
classA
scala>classB(giveA:Int,valb:Int)extendsA(giveA)
classB
scala>valx=newB(10,20)
x:B=B@14e554f
scala>x.a
res0:Int=10
scala>x.b
res1:Int=20class子類(子類對外接收的參數(shù))extends
超類(子類給超類的參數(shù))453.3重寫超類的成員三、類繼承金屬超類中的某個(gè)屬性可能并不一定符合子類的情況,子類需要一個(gè)新的符合子類行為的版本。固態(tài)液態(tài)重寫override成員定義
重寫超類的成員的語法防止意外的重寫改善了“脆弱基類”的問題463.3重寫超類的成員三、類繼承不可重寫的成員無參方法與字段final超類成員子類不可重寫final類類不可被繼承Scala在調(diào)用無參方法和調(diào)用同名的字段時(shí)形式相同無參方法字段重寫不能重寫方法的返回類型必須和字段的類型一致!473.3重寫超類的成員三、類繼承無參方法字段重寫不能重寫scala>classA{
|defjustA()="A"
|}
classA
scala>classBextendsA{
|overridevaljustA="B"
|}scala>classD{
|vald=10
|}
classD
scala>classEextendsD{
|overridedefd()=100
|}將無參方法重寫為字段將字段重寫為無參方法×√483.4子類型多態(tài)與動態(tài)綁定三、類繼承子類型多態(tài):類型為超類的變量可以指向子類的對象。對于方法:盡管變量的類型是超類,方法的版本卻是“動態(tài)綁定”的。調(diào)用的方法要運(yùn)行哪個(gè)版本,是由變量指向的對象來決定的scala>classA{
|defdisplay()="I'mA."
|}
classA
scala>classBextendsA{
|overridedefdisplay()="I'mB."
|}
classB
scala>valx:A=newB
valx:A=B@6ebece
scala>x.display()
valres0:String=I'mB.變量x的類型為超類A,但指向的對象為子類B的對象493.5抽象類三、類繼承如果類里包含了沒有具體定義的成員——沒有初始化的字段或沒有函數(shù)體的方法,那么這個(gè)類就是抽象類,必須用關(guān)鍵字“abstract”修飾。存在抽象成員:不能構(gòu)造出具體的對象,不能用“new”初始化?。ǔ橄箢悾┏惓蓡T:抽象子類成員:具體子類實(shí)現(xiàn)超類的抽象成員子類實(shí)現(xiàn)超類的抽象成員時(shí),關(guān)鍵字“override”可寫可不寫。503.5抽象類三、類繼承objectAbstractClass{
defmain(args:Array[String]):Unit={
//valx=newJ//抽象類不能通過“new”來構(gòu)造實(shí)例對象
//error:classJisabstract;cannotbeinstantiated
valy=newK(1)
//構(gòu)造子類的對象
println(y.j)//訪問被子類“實(shí)現(xiàn)”了超類的抽象成員j
println(y.k)//輸出:1
}
}
abstractclassJ{//定義抽象類J
valj:Int//聲明了抽象成員,沒有”定義“
}
classK(valk:Int)extendsJ{//定義子類K
valj=k*2//子類“實(shí)現(xiàn)”了超類的抽象成員j
}513.6Scala類的層次結(jié)構(gòu)三、類繼承/tour/unified-types.html抽象類,是所有類的超類值類引用類自定義的類Null:空引用,即指向JVM里的空內(nèi)存Nothing:所有值類和引用類的子類,甚至還是Null類的子類。不僅表示空引用,還表示空值523.6Scala類的層次結(jié)構(gòu)三、類繼承/tour/unified-types.html值類的隱式轉(zhuǎn)換scala>valx:Long=987654321
x:Long=987654321
scala>valy:Float=x
y:Float=9.8765434E8
scala>valz:Long=y
<console>:12:error:typemismatch;用于對象在兩個(gè)類之間進(jìn)行類型轉(zhuǎn)換53三、類繼承3.7小結(jié)類繼承的概念和方法子類調(diào)用超類的構(gòu)造方法重寫超類的成員子類型多態(tài)與動態(tài)綁定抽象類Scala類的層次結(jié)構(gòu)在編寫Chisel時(shí),類繼承主要用于編寫接口,使接口可以擴(kuò)展!54四、特質(zhì)554.1什么是特質(zhì)四、特質(zhì)特質(zhì)天生就是抽象的,可以包含抽象成員;但是不需要用“abstract”修飾,也不能用“new”來實(shí)例化。特質(zhì)內(nèi)部可以包含字段和方法,甚至包含其他單例對象、類和特質(zhì)的定義。單例對象、類、和特質(zhì)都可以混入特質(zhì),也可以用“override”來重寫特質(zhì)成員。Scala只允許繼承自一個(gè)類,但是對特質(zhì)的混入數(shù)量卻沒有限制。56scala>classA{
|vala="ClassA"
|}
definedclassA
scala>traitB{
|valb="TraitB"
|}
definedtraitB
scala>objectCextendsAwithB
definedobjectC
scala>C.a
res1:String=ClassA
scala>C.b
res2:String=TraitB
4.1什么是特質(zhì)四、特質(zhì)單例對象、類以及特質(zhì)在混入一個(gè)特質(zhì)后,就包含了特質(zhì)的所有公有成員。代碼舉例:可以用關(guān)鍵字“extends”繼承類或混入特質(zhì);當(dāng)混入多個(gè)特質(zhì)時(shí),后續(xù)關(guān)鍵字使用“with”。特質(zhì)的定義使用關(guān)鍵字“trait”,且不能有入?yún)ⅰ?74.2特質(zhì)的層次四、特質(zhì)特質(zhì)也可以繼承自其他類,或混入任意個(gè)特質(zhì)。在特質(zhì)沒有繼承和混入時(shí),那么這個(gè)特質(zhì)就是AnyRef類的子特質(zhì)。當(dāng)某個(gè)類、單例對象或特質(zhì)用關(guān)鍵字“extends”混入一個(gè)特質(zhì)時(shí),會隱式繼承自這個(gè)特質(zhì)的超類。特質(zhì)對混入有一個(gè)限制條件:類、單例對象和特質(zhì)混入特質(zhì)時(shí),它們的超類必須是待混入特質(zhì)的超類,或者是待混入特質(zhì)的超類的子類。58scala>classA
scala>classBextendsA
scala>classC
scala>traitDextendsA
scala>traitEextendsB
scala>classTest1extendsAwithD
definedclassTest1
scala>classTest2extendsBwithD
definedclassTest24.2特質(zhì)的層次四、特質(zhì)代碼舉例:特質(zhì)D繼承自類A特質(zhì)E繼承自類B類Test1的超類是類A特質(zhì)D的超類也是類A類Test2的超類是類B,也就是A的子類特質(zhì)D的超類也是類A59scala>classA
scala>classBextendsA
scala>classC
scala>traitDextendsA
scala>traitEextendsB
scala>classTest3extendsCwithD
<console>:13:error:illegalinheritance;superclassCisnota
subclassofthesuperclassAofthemixintraitD
classTest3extendsCwithD
^4.2特質(zhì)的層次四、特質(zhì)代碼舉例:類Test3的超類是類C特質(zhì)D的超類的類A604.3混入特質(zhì)的簡便方法四、特質(zhì)還可以在最前面加上一個(gè)想要繼承的超類:newTrait1withTrait2...{definition}newSuperClasswithTrait1withTrait2...{definition}實(shí)際上,此處定義了一個(gè)匿名類等效代碼:classAnonymousClassextendsTrait1withTrait2...{definition}
newAnonymousClass614.3混入特質(zhì)的簡便方法四、特質(zhì)代碼舉例:scala>traitA{
|vala="IcomefromtraitA!"
|}
definedtraitA
scala>traitB{
|valb="IcomefromtraitB!"
|}
definedtraitB
scala>valC=newAwithB
C:AwithB=$anon$1@5a058be5
scala>C.a
res0:String=IcomefromtraitA!
scala>C.b
res1:String=IcomefromtraitB!624.4特質(zhì)的線性化疊加計(jì)算四、特質(zhì)需要在特質(zhì)里定義同名同參的方法,并用關(guān)鍵字組合“abstractoverride”修飾。特質(zhì)對該方法的定義必須出現(xiàn)“super.方法名(參數(shù))”。abstractclassA{defm(s:String):String}
classXextendsA{defm(s:String)="X->"+s}
traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}
traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}
traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}
traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}
traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}
classGextendsX{overridedefm(s:String)="G->"+s}
valx=newGwithDwithEwithFwithB
println(x.m("End"))//G->D->C->E->F->B->End634.4特質(zhì)的線性化疊加計(jì)算四、特質(zhì)abstractclassA{defm(s:String):String}
classXextendsA{defm(s:String)="X->"+s}
traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}
traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}
traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}
traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}
traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}
classGextendsX{overridedefm(s:String)="G->"+s}
valx=newGwithDwithEwithFwithB
println(x.m("End"))//G->D->C->E->F->B->End該特質(zhì)必須混入某個(gè)擁有該方法具體定義的類中。需要混入特質(zhì)進(jìn)行線性化計(jì)算的類,在定義時(shí)不能立即混入特質(zhì)。644.5線性化計(jì)算公式四、特質(zhì)①G根據(jù)線性化計(jì)算公式得:abstractclassA{defm(s:String):String}
classXextendsA{defm(s:String)="X->"+s}
traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}
traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}
traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}
traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}
traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}
classGextendsX{overridedefm(s:String)="G->"+s}
valx=newGwithDwithEwithFwithB
println(x.m("End"))//G->D->C->E->F->B->End最左邊是類本身。654.5線性化計(jì)算公式四、特質(zhì)①G②G→B→A根據(jù)線性化計(jì)算公式得:藍(lán)色表示起點(diǎn),類X不參與計(jì)算abstractclassA{defm(s:String):String}
classXextendsA{defm(s:String)="X->"+s}
traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}
traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}
traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}
traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}
traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}
classGextendsX{overridedefm(s:String)="G->"+s}
valx=newGwithDwithEwithFwithB
println(x.m("End"))//G->D->C->E->F->B->End類的右邊寫定義時(shí)最后混入的特質(zhì),并接著往右按繼承順序?qū)懺撎刭|(zhì)的所有超類和超特質(zhì)。664.5線性化計(jì)算公式四、特質(zhì)①G②G→B→A③G→B→A→F→C→A④G→B→A→F→C→A→E→C→A⑤G→B→A→F→C→A→E→C→A→D→A根據(jù)線性化計(jì)算公式得:藍(lán)色表示起點(diǎn),紅色表示重復(fù),類X不參與計(jì)算abstractclassA{defm(s:String):String}
classXextendsA{defm(s:String)="X->"+s}
traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}
traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}
traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}
traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}
traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}
classGextendsX{overridedefm(s:String)="G->"+s}
valx=newGwithDwithEwithFwithB
println(x.m("End"))//G->D->C->E->F->B->End繼續(xù)往右寫下倒數(shù)第二個(gè)混入的特質(zhì),以及其超類和超特質(zhì),直到寫完所有特質(zhì)。674.5線性化計(jì)算公式四、特質(zhì)①G②G→B→A③G→B→A→F→C→A④G→B→A→F→C→A→E→C→A⑤G→B→A→F→C→A→E→C→A→D→A⑥G→B→F→E→C→D→A⑦G→B→F→E→C→D→A→AnyRef→Any根據(jù)線性化計(jì)算公式得:藍(lán)色表示起點(diǎn),紅色表示重復(fù),類X不參與計(jì)算abstractclassA{defm(s:String):String}
classXextendsA{defm(s:String)="X->"+s}
traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}
traitCextendsA{abstractoverridedefm(s:String)=super.m("C->"+s)}
traitDextendsA{abstractoverridedefm(s:String)=super.m("D->"+s)}
traitEextendsC{abstractoverridedefm(s:String)=super.m("E->"+s)}
traitFextendsC{abstractoverridedefm(s:String)=super.m("F->"+s)}
classGextendsX{overridedefm(s:String)="G->"+s}
valx=newGwithDwithEwithFwithB
println(x.m("End"))//G->D->C->E->F->B->End所有重復(fù)項(xiàng)只保留最右邊的,并在后面加上AnyRef和Any。684.4特質(zhì)的線性化疊加計(jì)算四、特質(zhì)若類G的m方法也有superX->G->D->C->E->F->B->EndabstractclassA{defm(s:String):String}
classXextendsA{defm(s:String)="X->"+s}
traitBextendsA{abstractoverridedefm(s:String)=super.m("B->"+s)}
traitCextendsA{abstract
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年內(nèi)蒙古建筑職業(yè)技術(shù)學(xué)院單招職業(yè)技能筆試模擬試題帶答案解析
- 2026年江西環(huán)境工程職業(yè)學(xué)院單招職業(yè)技能考試備考試題帶答案解析
- 2025-2030衛(wèi)星測控技術(shù)行業(yè)市場供需現(xiàn)狀與投資評估規(guī)劃分析研究報(bào)告
- 2025-2030醫(yī)療云計(jì)算平臺數(shù)據(jù)安全與隱私保護(hù)解決方案報(bào)告
- 2025-2030區(qū)塊鏈技術(shù)金融領(lǐng)域應(yīng)用現(xiàn)狀發(fā)展投資前景競爭格局規(guī)劃分析公告
- 2025-2030制造環(huán)境行業(yè)市場供需分析及清潔生產(chǎn)投資評估規(guī)劃分析研究報(bào)告
- 2025-2030制造業(yè)升級分析及產(chǎn)能布局趨勢與投資方向研究報(bào)告
- 2025-2030制漿造紙投資帶動增長分析政策排序計(jì)劃
- 2025-2030制冷設(shè)備制造業(yè)發(fā)展現(xiàn)狀與市場競爭力綜合分析報(bào)告
- 2026年重慶財(cái)經(jīng)職業(yè)學(xué)院高職單招職業(yè)適應(yīng)性測試備考試題帶答案解析
- 產(chǎn)品質(zhì)量鑒定通用程序規(guī)范
- 中橋施工組織設(shè)計(jì)方案
- 一類,二類,三類醫(yī)療器械分類目錄
- 醫(yī)療機(jī)構(gòu)開展健康體檢服務(wù)申請表
- 合同相對方主體資格資質(zhì)資信審查指引
- 健康相關(guān)生存質(zhì)量及其測量和評價(jià)課件
- 口服液生產(chǎn)過程監(jiān)控記錄
- 富士相機(jī)使用說明書
- GB/T 18271.1-2017過程測量和控制裝置通用性能評定方法和程序第1部分:總則
- 道路交通安全知識培訓(xùn)(經(jīng)典)課件
- 單為民、血栓與止血常規(guī)七項(xiàng)檢測課件
評論
0/150
提交評論