Scala混入多重繼承、類型層次和集合怎么實(shí)現(xiàn)

本篇內(nèi)容主要講解“Scala混入多重繼承、類型層次和集合怎么實(shí)現(xiàn)”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Scala混入多重繼承、類型層次和集合怎么實(shí)現(xiàn)”吧!

成都創(chuàng)新互聯(lián)公司長(zhǎng)期為成百上千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為溫泉企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、做網(wǎng)站,溫泉網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。

用特征來(lái)實(shí)現(xiàn)混入(mix-in)式的多重繼承

Scala里相當(dāng)于Java接口的是特征(Trait)。Trait的英文意思是特質(zhì)和性狀(本文稱其為特征),實(shí)際上他比接口還功能強(qiáng)大。與接口不同的是,它還可以定義屬性和方法的實(shí)現(xiàn)。Scala中特征被用于服務(wù)于單一目的功能模塊的模塊化中。通過(guò)混合這種特征(模塊)群來(lái)實(shí)現(xiàn)各種應(yīng)用程序的功能要求,Scala也是按照這個(gè)構(gòu)想來(lái)設(shè)計(jì)的。

一般情況下Scala的類只能夠繼承單一父類,但是如果是特征的話就可以繼承多個(gè),從結(jié)果來(lái)看就是實(shí)現(xiàn)了多重繼承。這可以被認(rèn)為是同Ruby模塊基本相同的功能。就看一下下面的例子吧。為了辨認(rèn)方便,此后的特征名稱前都加上前綴字母T。特征既可以繼承類也可以繼承其他特征。

class Person ; //實(shí)驗(yàn)用的空類,如果使用了上一次的Person類,則下面的  //PianoplayingTeacher類就需要構(gòu)造參數(shù)了  trait TTeacher extends Person {  def teach //虛方法,沒(méi)有實(shí)現(xiàn)  }  trait TPianoPlayer extends Person {  def playPiano = {println("I’m playing piano. ")} //實(shí)方法,已實(shí)現(xiàn)  }  class PianoplayingTeacher extends Person with TTeacher with TPianoPlayer {  def teach = {println("I’m teaching students. ")} //定義虛方法的實(shí)現(xiàn)  }

如上所示,可以連著多個(gè)with語(yǔ)句來(lái)混合多個(gè)特征到一個(gè)類中。***個(gè)被繼承源用extends,第二個(gè)以后的就用with語(yǔ)句。正如大家所知道的,可以生成實(shí)例的是非抽象(abstract)的類。另外請(qǐng)注意一下從特征是不可以直接創(chuàng)建實(shí)例的。

那么就實(shí)際運(yùn)行一下吧。

scala> val t1 = new PianoplayingTeacher  t1: PianoplayingTeacher = PianoplayingTeacher@170a650 scala> t1.playPiano  I’m playing piano.  scala> t1.teach  I’m teaching students.

實(shí)際上如下所示,可以在創(chuàng)建對(duì)象時(shí)才將特征各自的特點(diǎn)賦予對(duì)象。

scala> val tanakaTaro = new Person with TTeacher with TPianoPlayer {  | def teach = {println("I'm teaching students.")} }  tanakaTaro: Person with TTeacher with TPianoPlayer = $anon$1@5bcd91 scala> tanakaTaro playPiano  I’m playing piano.  scala> tanakaTaro teach  I'm teaching students.

用特征來(lái)方便地實(shí)現(xiàn)面向方面的編程

充分利用特征的功能之后,就能方便地實(shí)現(xiàn)現(xiàn)今流行的面向方面編程(AOP)了。

首先,用特征來(lái)聲明表示基本動(dòng)作方法的模塊Taction。

trait TAction {  def doAction  }

接著作為被加入的方面,定義一下加入了前置處理和后置處理的特征TBeforeAfter。

trait TBeforeAfter extends TAction {  abstract override def doAction {  println("/entry before-action") //doAction的前置處理  super.doAction // 調(diào)用原來(lái)的處理  println("/exit after-action") //doAction的后置處理  }  }

通過(guò)上面的abstract override def doAction {}語(yǔ)句來(lái)覆蓋虛方法。具體來(lái)說(shuō)這當(dāng)中的super.doAction是關(guān)鍵,他調(diào)用了TAction的doAction方法。其原理是,由于doAction是虛方法,所以實(shí)際被執(zhí)行的是被調(diào)用的實(shí)體類中所定義的方法。

那么將實(shí)際執(zhí)行的實(shí)體類RealAction作為T(mén)Action的子類來(lái)實(shí)現(xiàn)吧。

class RealAction extends TAction {  def doAction = { println("** real action done!! **") }  }

接著就執(zhí)行一下。

scala> val act1 = new RealAction with TBeforeAfter  act1: RealAction with TBeforeAfter = $anon$1@3bce70 scala> act1.doAction  /entry before-action  ** real action done!! **  /exit after-action

僅僅這樣還不好玩,接著為他定義一下別的方面,然后將這些方面加入到同一對(duì)象的方法中。接著定義一個(gè)將源方法執(zhí)行兩遍的方面。

trait TTwiceAction extends TAction {  abstract override def doAction {  for ( i <- 1 to 2 ) { // 循環(huán)執(zhí)行源方法的方面  super.doAction // 調(diào)用源方法doAction  println( " ==> No." + i )  }  }  }

下面,將TBeforeAfter和TtwiceAction混合在一起后執(zhí)行一下。

scala> val act2 = new RealAction with TBeforeAfter with TTwiceAction  act2: RealAction with TBeforeAfter with TTwiceAction = $anon$1@1fcbac1 scala> act2.doAction  /entry before-action  ** real action done!! **  /exit after-action  ==> No.1 /entry before-action  ** real action done!! **  /exit after-action  ==> No.2

伴隨著原來(lái)方法的before/after動(dòng)作一起各自執(zhí)行了兩次。接著將混入順序顛倒后再試一下。

scala> val act3 = new RealAction with TTwiceAction with TBeforeAfter  act3: RealAction with TTwiceAction with TBeforeAfter = $anon$1@6af790 scala> act3.doAction  /entry before-action  ** real action done!! **  ==> No.1 ** real action done!! **  ==> No.2 /exit after-action

這樣執(zhí)行后,原來(lái)的實(shí)現(xiàn)方法被循環(huán)執(zhí)行了兩次,但是before/after則在循環(huán)以外整體只執(zhí)行了一次。這是根據(jù)with語(yǔ)句定義的順序來(lái)執(zhí)行的,知道了這原理之后也就沒(méi)有什么奇怪的了。Scala特性的如此混入順序是和AspectJ的方面以及Spring的interceptor相同的。

這樣不僅是before和after動(dòng)作,只要更改了特征的實(shí)現(xiàn)就可以將各種方面動(dòng)態(tài)地加入到原來(lái)的對(duì)象中去了,讀者自己也可以嘗試一下各種其他情況。

在Java中通過(guò)Decorator或Template Method模式來(lái)想盡辦法實(shí)現(xiàn)的功能,在Scala中只要通過(guò)特征就可以輕松到手了。從這還可以延展開(kāi)來(lái),通過(guò)在原來(lái)的方法中插入掛鉤的方法,即所謂的攔截者式面向方面的方法,就可以輕松地將各個(gè)方面通過(guò)特征來(lái)組件化了。

請(qǐng)讀者如果想起Scala是怎樣的強(qiáng)類型和靜態(tài)化語(yǔ)言的話,那么就能夠明白通過(guò)特征來(lái)加入新功能的特

點(diǎn)給他帶來(lái)了多大的靈活性。

Scala的類型體系(基本類型)

Scala中可使用的基本數(shù)據(jù)都以類的形式被定義了,所以基本類型與用戶定義類型可以認(rèn)為是沒(méi)有區(qū)別的。雖然這么說(shuō),Scala還是提供了與Java的數(shù)據(jù)類型相對(duì)應(yīng)的類定義群(圖 4-1)。這絕不是包裝類,在編譯后他們將被映射為Java的字節(jié)碼,所以性能上是絕對(duì)沒(méi)有問(wèn)題的。

Scala混入多重繼承、類型層次和集合怎么實(shí)現(xiàn)

圖 4-1與Scala基本類型相對(duì)應(yīng)的類群

如下例程序所示,對(duì)于整數(shù)對(duì)象7可以響應(yīng)各種消息(方法)。既可以執(zhí)行toString方法來(lái)轉(zhuǎn)換成字符串,又可以使用to這個(gè)執(zhí)行Int => Range的方法。附帶說(shuō)一下,7 to 20相當(dāng)于7.to(20),該方法的執(zhí)行結(jié)果是Range(7,8, 9, … 19, 20)。對(duì)于該范圍對(duì)象適用了foreach( (i)=>print(i) ),print _則與一個(gè)參數(shù)的匿名函數(shù)(i) => print(i)相當(dāng)。

scala> 7.toString  res2: java.lang.String = 7 scala> 7 to 20 foreach( print _ )  7891011121314151617181920

實(shí)際上,Scala在編譯器自動(dòng)引入的Predef單例對(duì)象中定義了為了兼容Java基礎(chǔ)類型所存在的類型別名。例如boolean, char, byte, short, int, long, float, double被定義了,這些別名實(shí)際上是引用了Scala.Boolean,Scala.Char,Scala.Byte等Scala的類??赡艿脑挘瑸榱颂岣摺癝cala中說(shuō)所有數(shù)據(jù)都是對(duì)象”這種意識(shí),建議盡量一開(kāi)始就使用Int、Boolean、Float等原來(lái)的類名。

不過(guò),在Scala種并沒(méi)有類型轉(zhuǎn)換操作符,而是在所有類的基類Any中定義了具有同等功能的方法asInstanceOf[X]。用這方法就可以把類型轉(zhuǎn)換為X了。Any類中同時(shí)還定義了相當(dāng)于instanceof操作符的isInstanceOf[X]方法。

Scala混入多重繼承、類型層次和集合怎么實(shí)現(xiàn)

圖 4-2Scala類層次的基本結(jié)構(gòu)

特別是該類層次中Iterable下的集類型在函數(shù)式編程中大顯身手。其中的可變(mutable)與非可變(immutable)兩大系列的類層次基本上呈現(xiàn)出鏡像關(guān)系,可以充分發(fā)揮出函數(shù)式語(yǔ)言功能的當(dāng)然就是非可變集類型群了。

到此,相信大家對(duì)“Scala混入多重繼承、類型層次和集合怎么實(shí)現(xiàn)”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

網(wǎng)頁(yè)標(biāo)題:Scala混入多重繼承、類型層次和集合怎么實(shí)現(xiàn)
URL鏈接:http://muchs.cn/article18/ghjddp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT網(wǎng)站維護(hù)、全網(wǎng)營(yíng)銷推廣動(dòng)態(tài)網(wǎng)站、網(wǎng)站營(yíng)銷、微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)