Scala 系列 特質 Trait

2021-10-06 04:06:12 字數 3382 閱讀 3967

本文主要對scala中特質的概念與使用進行介紹

特質是scala裡面**復用的基礎單元

與 python 不同,python 子類可以繼承自多個父類,而 scala 不允許乙個類從從個超類繼承,只能繼承唯一的超類。

但是 scala 允許乙個類混入任意數量的特質,混入就是指類使用了特質提供的方法。

那麼特質在 scala 中是如何定義的呢?

類的定義使用關鍵字class,特質的定義使用關鍵字trait

scala 中的特質既可以有普通欄位和普通方法也可以有抽象欄位和抽象方法。如果特質中只有抽象內容,叫做瘦介面;如果既有抽象內容也有具體內容,叫做富介面

// 特質t的定義

trait t

// 特質中未被實現的方法預設就是抽象方法,不需要關鍵字修飾

def ap()

// 普通字段

val sn =

"******"

// 抽象字段

var an

}// 特質a混入類a

// 混入乙個特質使用 extends 關鍵字

// 混入多個特質則是 extends trait_a with trait_b with ...

class

aextends

t// 重寫特質中有具體實現的方法 用override 關鍵字

override def p()

// 重寫特質中的抽象方法 不需要override關鍵字

def ap()

// 類a自帶的字段

val asn =

"a******"

// 重新抽象字段

var an =

"an"

}

混入特質的類重寫特質的普通方法需要override 關鍵字,重寫抽象方法不需要override 關鍵字。特質中的抽象方法在類中必須被重寫。

混入特質的類會自動獲得特質的普通字段,以上述**為例,為sn字段,但是這些字段不是被繼承的,只是簡單的被加入到了子類當中,是該類自己的字段,與asn字段地位相同。而特質中的抽象字段在子類中的必須被重寫,不需要 override 關鍵字。

帶特質的物件

有時候我們希望在不改變類繼承體系的情況下,對類物件的功能進行臨時增強或者擴充套件

var/val 物件名 =

new 類名 with 特質名

object test 

class

messageworker

def main

(args: array[string]

): unit =

}

特質的構造

和類的主構造器不同,特質的構造器不能有引數。

構造器按照如下的順序執行:

以下面**為例

object test

trait b

extends

a trait c

extends

aclass

dclass

eextends

d with c with b

def main

(args: array[string]

): unit =

}

// 列印結果為

class

dtrait a

trait c

trait b

class

e

疊加特質

可以為類或物件新增多個互相呼叫( 呼叫順序 從右向左 )的特質,對於需要分階段加工處理某個值的場景很有用。

object test

} trait fe

extendsml}

trait fen

extendsml}

trait dp

extendsml}

class

pextends

fe with fen with dp

} def main

(args: array[string]

): unit =

}

// pipeline方法執行結果如下

input data

start pipeline

data preprocessing

feature engineering

feature selection

選擇模型及超引數

finish model

特質繼承類

特質可以繼承類,而這個類會成為所有混入該特質的超類。

因為在 scala 中,乙個類只能有乙個超類,所以以如下**為例說明注意事項

class

atrait b

extends

a// 合法 因為c擴充套件的類是特質b超類的乙個子類

class

cextends

a with b

class

d// 不合法 因為e擴充套件的類不是特質b超類的子類

class

eextends

d with b

當特質中有多個抽象方法,而我們只需要用到其中的乙個或幾個方法的時候,直接去「繼承」該特質明顯是不明智的選擇,因為那意味著我們需要重寫該特質內的所有抽象方法。這時候我們去定義乙個抽象類「繼承」該特質,重寫特質中的抽象方法,使方法體為空,然後再定義我們需要的類去繼承該抽象類比較好。

trait a

abstract

class

bextends

aclass

cextends

b

參考資料:

《快學scala》

《scala程式設計》

Scala基礎 7 特質(Trait)

特質定義使用關鍵字trait trait carid上面定義了乙個trait,裡面包含乙個抽象欄位id和抽象方法currentid。注意,抽象方法不需要使用abstract關鍵字,特質中沒有方法體的方法,預設就是抽象方法。trait定義好之後,就可以使用extends或with關鍵字將trait混入...

scala學習之特質 trait

特質,很像j a中的介面,但是又有些不同,比如實現方法,當然j a8也可以在介面中實現乙個方法了,但是只能定義乙個default方法。當做介面使用 特質 trait logger trait consolelogger extends logger 不需要寫 overrride 在重寫 特質的抽象方...

scala學習(十五) trait

下面是乙個trait的簡單例子,裡面包含的trait的基本用法,trait的繼承 trait logger def warn msg string trait logger2 trait logger3 import scala.reflect.class dog extends logger wi...