2016-07-15 174 views
2

我有以下結構:與混入特質豐富對象

trait Runner { 
    def run: Unit 
} 

trait LoggableRunner extends Runner { 
    abstract override def run { 
    println("logging enter") 
    super.run 
    println("logging exit") 
    } 
} 

class RealRunner extends Runner { 
    def run = println("running...") 
} 

這樣我可以豐富我的日誌類以下列方式:

val a = new RealRunner with LoggableRunner 

它增加前和運行後登錄信息run方法。

現在我真正想要的是能夠構建具有特徵的scala對象。我曾嘗試以同樣的方式:

object RealRunner extends LoggableRunner{ 
    def run = println("running...") 
} 

,但我得到:method run needs override modifier

所以,我想:

object RealRunner extends LoggableRunner{ 
     override def run = println("running...") 
    } 

,但我得到:method run needs abstract override modifiers。所以我再次嘗試添加抽象,我得到:abstract override modifier only allowed for members of traits

甚至可能將特質混合到物體中?

+0

嗯,我不知道_why_它是這樣做的,但是你可以分兩步做你想做的事情:首先定義一個class class RealRunner extends Runner {def print = {...}}',然後: '對象RealRunner使用LoggableRunner擴展RealRunner'。 – Dima

+0

這樣一個瘋狂的用例:) – ipoteka

+0

@ipoteka「瘋狂」? – Dima

回答

1

我不知道爲什麼它的行爲這種方式(確實顯得怪異和混亂,希望有人用更多的線索會解囊,而流下的原因在此的一些光),但這裏是你如何能做到什麼你想要:

trait Runner { 
    def run =() // making it non-abstract, makes things a lot easier! 
} 

trait LoggableRunner extends Runner { 
    override def run = { 
     println("start") 
     super.run 
     println("stop") 
    } 
    def foo = "foo" 
} 

trait RealRunner extends Runner { self: LoggableRunner => 
    override def run = println(foo) // uses things from LoggableRunner 
} 

object RealRunner extends RealRunner with LoggableRunner 

scala> RealRunner.run 
start 
foo 
stop 

嗚呼!

+0

嘿,太棒了!還有一個問題 - 我如何在你的解決方案中堆疊特質? - 例如我想補充一個特點被稱爲LoggableRunnerAB有輸出,如: '啓動市場 開始 富 停止 stopB' – NNamed

+0

@NNamed的常用方法:'對象RealRunner與LogabbleRunner延伸RealRunner與LogabbleRunnerAB'應該這樣做。 – Dima