2016-07-15 175 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