2011-07-27 76 views
21

我想創建一個特性,混合時將用一個方法替換一個方法的默認定義,調用原始方法,然後操作結果。調用scala中的自我類型特性的超類方法

這裏就是我想要做的事:

class Foo { 
    def bar() : String = "Foos bar" 
} 

trait OtherStuff { 
    self : Foo => 
    def bar() : String = self.bar() + " with OtherStuff" 
} 

class Quux extends Foo with OtherStuff 

如果這個工作我想它,然後(new Quux).bar將現在回到Foos bar with OtherStuff的方式。不幸的是,它不工作的方式 - 我得到的是:

<console>:6: error: error overriding method bar in class Foo of type()String; 
method bar in trait OtherStuff of type()String needs `override' modifier 
     class Quux extends Foo with OtherStuff 

但是如果我定義OtherStuff時使用override,我得到:

<console>:7: error: method bar overrides nothing 
     override def bar() : String = self.bar() + " with OtherStuff" 

是否有可能重寫的方法自我使用特質?如果沒有,會改變OtherStuff是一個特質是extends Foo而不是一個具有自我型Foo做什麼壞事所有存在說出類似

class WhatEver extends Foo with Xyz with Pqr with OtherStuff with Abc 

我在斯卡拉2.7使用的代碼。 7因爲這是一個構建規則,我們還沒有將我們的sbt項目升級到0.10.x版本。 (我們依賴的插件還沒有準備好)

回答

29

您需要abstract override而沒有自我類型。

trait OtherStuff extends Foo {         
    abstract override def bar() = super.bar() + " with OtherStuff" 
} 

然後class Quux extends Foo with OtherStuff做你想做的。

This article可能是感興趣的。

+3

如果OtherStuff在我的邏輯中不是Foo呢?沒有extendig Foo沒有另一種解決方案嗎?或者我在這裏濫用自我打字? – Radian

+0

@Dupont:爲什麼Quux類應該使用OtherStuff擴展Foo,而不是擴展OtherStuff並從繼承中獲得Foo? – polo

0

,或者你可以像下面

class Foo { 
    def bar() : String = "Foos bar"} 
trait OtherStuff { 
    self : Foo => 
    def bar(s : String) : String = self.bar() + s} 

class Quux extends Foo with OtherStuff 
(new Quux).bar(" with other stuff") 

一個超載的事情是,有自我類型的註釋,「其他東西」,在OtherStuff定義是美孚的一部分,當 特質與富混合,而不是一個子類型的關係。

+2

你剛剛定義了一個無限遞歸函數。 –

+2

@TonyK:不,因爲兩個'bar'方法的簽名是不同的 –