[7] - trait

當(dāng)你開始使用繼承來重用代碼時怜瞒,你入門了糟需;當(dāng)你開始避免使用繼承來重用代碼時忘晤,你成熟了

這是我以前在知乎上看到關(guān)于類繼承作用的回答,雖不完全正確齿桃,卻十分明確的表達(dá)出了好的代碼應(yīng)避免類繼承而盡量使用類組合惑惶。Scala 顯然也非常贊同這一點,以至于有了 trait短纵,又叫做特質(zhì)带污。當(dāng)我們定義特質(zhì)時,應(yīng)該要遵循這樣的原則:一個 trait 只干一件事香到,如果要干多件事鱼冀,就定義多個 trait,然后使用一個類來 extends 這些 traits

定義 trait

trait 的定義與 class 類似:

scala> trait T {
     | }
defined trait T

當(dāng)然悠就,trait 可以包含成員和方法千绪,并且:

  • trait 中的成員可以僅聲明,也可以聲明并指定值
  • trait 中的方法可以有實現(xiàn)梗脾,也可以只有聲明而沒有實現(xiàn)
scala> trait T {
     |   val a: Int
     |   val b: Int = 1
     |
     |   def getA(): Int
     |   def getB() = b
     | }
defined trait T

對比而言荸型,類一旦包含未定義的方法就必須聲明為 abstract;而 Java 的接口中的方法是不能實現(xiàn)的炸茧,必須是抽象方法帆疟。如果 trait 既為實現(xiàn)它所聲明的方法,也沒有定義或聲明其他成員宇立,那么在字節(jié)碼級別,該 trait 其實是接口是相同的

另一個與類不同的是自赔,trait 主構(gòu)造函數(shù)不允許有參數(shù)列表妈嘹,并且不允許為 trait 定義輔助構(gòu)造函數(shù)

混入多個 trait

Scala 類只能有一個父類,但可以混入多個 trait绍妨,當(dāng)要混入多個 traits 或已經(jīng)繼承了某個父類時润脸,需要使用關(guān)鍵字 with柬脸,如下例:

scala> trait T {
     |   val a: Int
     |   val b: Int = 1
     |
     |   def getA(): Int
     |   def getB() = b
     | }
defined trait T

scala>

scala> trait Q {
     |   def currentTime: String = System.currentTimeMillis().toString
     | }
defined trait Q

scala>

scala> class X extends T with Q {
     |   override val a = 1
     |   override def getA(): Int = a
     | }
defined class X

當(dāng)類混入 trait 時,需要實現(xiàn) trait 中為實現(xiàn)的成員和方法毙驯。要混入多個 trait 是為了保證『高內(nèi)聚』倒堕,通俗說就是一個 trait 只干一件事,如果要干多件事爆价,就定義多個 trait 然后混入它們


當(dāng)你繼承的父類和混入的特質(zhì)或混入的不同特質(zhì)之間有同名方法時可能會有沖突垦巴,分為以下幾種情況:

  • trait 中的方法未實現(xiàn):不會沖突
scala> class C {
     |   def a: String = "a"
     | }
defined class C

scala>

scala> trait T {
     |   def a: String
     | }
defined trait T

scala>

scala> trait Q extends C with T {}
defined trait Q
  • trait 中的方法實現(xiàn)了且與父類中的方法參數(shù)列表及返回類型相同:會沖突
scala> class C {
     |   def a: String = "a"
     | }
defined class C

scala>

scala> trait T {
     |   def a: String = ""
     | }
defined trait T

scala>

scala> trait Q extends C with T {}
<console>:9: error: trait Q inherits conflicting members:
  method a in class C of type => String  and
  method a in trait T of type => String
(Note: this can be resolved by declaring an override in trait Q.)
       trait Q extends C with T {}
             ^
  • trait 中的方法實現(xiàn)了且與父類中的參數(shù)列表相同,返回類型不同:會沖突
scala> class C {
     |   def a: String = "a"
     | }
defined class C

scala>

scala> trait T {
     |   def a: Int = 1
     | }
defined trait T

scala>

scala> trait Q extends C with T {}
<console>:9: error: trait Q inherits conflicting members:
  method a in class C of type => String  and
  method a in trait T of type => Int
(Note: this can be resolved by declaring an override in trait Q.)
       trait Q extends C with T {}
             ^
  • trait 中的方法實現(xiàn)了且與父類的參數(shù)列表不同铭段,返回類型相同:不會沖突
scala> class C {
     |   def a: String = "a"
     | }
defined class C

scala>

scala> trait T {
     |   def a( i: Int ): String = i.toString
     | }
defined trait T

scala>

scala> trait Q extends C with T {}
defined trait Q

trait 的繼承

一個 trait 同樣可以混入其他 trait 或繼承類:

scala> class C {
     |   def currentTime: String = System.currentTimeMillis().toString
     | }
defined class C

scala>

scala> trait T {
     |   def random: Int
     | }
defined trait T

scala>

scala> trait Q extends C with T {}
defined trait Q

雖然 Scala 語言支持你這么做骤宣,但我個人并不推薦


**傳送門: **Scala 在簡書目錄


歡迎關(guān)注我的微信公眾號:FunnyBigData

FunnyBigData
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市序愚,隨后出現(xiàn)的幾起案子憔披,更是在濱河造成了極大的恐慌,老刑警劉巖爸吮,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芬膝,死亡現(xiàn)場離奇詭異,居然都是意外死亡形娇,警方通過查閱死者的電腦和手機锰霜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來埂软,“玉大人锈遥,你說我怎么就攤上這事】迸希” “怎么了所灸?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長炫七。 經(jīng)常有香客問我爬立,道長,這世上最難降的妖魔是什么万哪? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任侠驯,我火速辦了婚禮,結(jié)果婚禮上奕巍,老公的妹妹穿的比我還像新娘吟策。我一直安慰自己,他們只是感情好的止,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布檩坚。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪匾委。 梳的紋絲不亂的頭發(fā)上拖叙,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音赂乐,去河邊找鬼薯鳍。 笑死,一個胖子當(dāng)著我的面吹牛挨措,可吹牛的內(nèi)容都是我干的挖滤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼运嗜,長吁一口氣:“原來是場噩夢啊……” “哼壶辜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起担租,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤砸民,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后奋救,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岭参,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年尝艘,在試婚紗的時候發(fā)現(xiàn)自己被綠了演侯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡背亥,死狀恐怖秒际,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情狡汉,我是刑警寧澤娄徊,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站盾戴,受9級特大地震影響寄锐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尖啡,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一橄仆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧衅斩,春花似錦盆顾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惫搏。三九已至,卻和暖如春蚕涤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铣猩。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工揖铜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人达皿。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓天吓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親峦椰。 傳聞我的和親對象是個殘疾皇子龄寞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 這篇講義只講scala的簡單使用,目的是使各位新來的同事能夠首先看懂程序汤功,因為 scala 有的語法對于之前使用習(xí)...
    MrRobot閱讀 2,912評論 0 10
  • 將trait作為接口使用Scala中的Triat是一種特殊的概念物邑,可以將Trait作為接口來使用,此時的Triat...
    sunnyzhu92閱讀 834評論 0 0
  • 一直想做一個繪畫基礎(chǔ)的教程滔金。沒有太多時間做不了視頻的教程色解,然后就做一個我覺得能表達(dá)清楚的文字的教程吧。 對于零基礎(chǔ)...
    懿暖醬閱讀 2,037評論 7 5
  • 七點鐘餐茵,我餓著肚子開始上課 廚房里的他在井井有條的做飯 我感動之余 不免心酸 我要找這樣一個善待我的人 看得清我的...
    躲起來的攖寧閱讀 72評論 0 0
  • 許巍的新專輯出了 是個叫高曉松的矮大緊作的詞 兩者的結(jié)合 產(chǎn)生了奇妙的化學(xué)反應(yīng) 最近刷遍朋友圈的心靈雞湯文 全都在...
    Luns醬閱讀 1,715評論 0 0