1. 程式人生 > >Spark學習(11)——scala面向物件程式設計(trait)

Spark學習(11)——scala面向物件程式設計(trait)

trait基礎知識-將trait作為介面使用

Scala中的trait是一種特殊的概念,首先我們可以將trait作為介面來使用,此時的trait就與Java中的介面非常類似,在Trait中可以定義抽象方法,就與抽象類中的抽象方法一樣,只要不給出方法的具體實現即可,類可以使用extends關鍵字繼承Trait,注意,這裡不是implement,而是extends,在scala中沒有implement的概念,無論繼承類還是Trait,統一都是extends

類繼承Trait後,必須實現其中的抽象方法,實現時不要使用override關鍵字,scala不支援對類進行多繼承,但是支援多重繼承Trait

,使用with關鍵字即可

執行結果

trait基礎知識-在trait中定義具體方法

trait基礎知識-在trait中定義具體欄位

Scala中的trait可以定義具體的field,此時繼承trait的類就自動獲得了trait中定義的field,但是這種獲取field的方式與繼承class是不同的,如果是繼承class獲取的field,實際是定義在父類中的,而繼承trait獲取的field,就直接被新增到了類中

trait基礎知識-在trait中定義抽象欄位

Scala中的trait可以定義抽象field,而trait中的具體方法則可以基於抽象field來編寫,

但是繼承

trait的類,則必須覆蓋抽象field,提供具體的值

執行結果

trait高階知識-為例項物件混入trait

有時我們可以在建立類的物件時,指定該物件混入某個trait,這樣,就只有這個物件混入該trait的方法,而類的其他物件則沒有

執行結果

可以看到p1呼叫sayHello的時候沒有列印log,而p2混入Mylogger這個trait後,打印出了log

trait高階知識-trait呼叫鏈

Scala中支援讓類繼承多個trait後,依次呼叫多個trait中的同一個方法,只要讓多個trait的同一個方法中,在最後都執行supper方法即可,類中呼叫多個trait

中都有的這個方法時,首先會從最右邊的trait的方法開始執行,然後依次往左執行,形成一個呼叫鏈條,這種特性非常強大,其實就相當於設計模式中的責任鏈模式的一種具體實現依賴

執行結果

從結果中可以看出,trait的呼叫鏈執行從右向左

trait高階知識-在trait中覆蓋抽象方法

Trait中,是可以覆蓋父trait的抽象方法的,但是覆蓋時,如果使用了super.方法的程式碼,則無法通過編譯,因為super.方法就會用父trait的抽象方法,此時子trait的該方法還是會被認為是抽象的,此時如果要通過編譯,就是給子trait的方法加上abstract override修飾

trait高階知識-混合使用trait的具體方法和抽象方法

Trait,可以混合使用具體方法和抽象方法,可以讓具體方法依賴於抽象方法,而抽象方法則放到繼承trait的類中去實現,這種trait其實就是設計模式中的模板設計模式的體現

trait高階知識-trait的構造機制

scala中,trait也是有構造程式碼的,也就是trait中的,不包含在任何方法中的程式碼,而繼承了trait的類的構造機制如下:1父類的建構函式執行2trait的構造程式碼執行,多個trait從左到右依次執行;3、構造trait時會先構造父trait,如果多個trait繼承同一個父trait,則父trait只會構造一次,4、所有trait構造完畢之後,子類的建構函式執行

trait高階知識-trait  field的初始化

scala中,trait是沒有接收引數的建構函式的,這是traitclass的唯一區別,但是如果需求就是要trait能夠對field進行初始化,該怎麼辦呢?只能使用scala中非常特殊的一種高階特性---提前定義

另外一種方式就是使用lazy value

trait高階知識-trait繼承class

scala中,trait也可以繼承自class,此時這個class就會成為所有繼承改trait的類的父類