2017-09-02 29 views
0

如何強制scala中的特徵只能被對象(不是類,特徵等)擴展?強制性狀由一個對象實現

我有以下星座:

trait Outer { self: SomeOtherClass => 
    def member: Inner.type = Inner 

    /* some other methods... */ 

    trait Inner { iself => 
    def parent: self.type = self 
    /* other methods... */ 
    } 
} 

我的問題是:我怎麼能強制執行內部特質必須通過的對象來實現(如對象內延伸內{...})?

我希望每個實現Outer的類都有一個內部對象,它攜帶一些狀態+從外部獲取內部的可能性,反之亦然。

最好的問候,

約亨

編輯:

例子:

// compiles 
class C extends Outer { 
    object Inner extends Inner { ... } 
} 

// doesn't compile 
class C extends Outer { 
    class Inner extends Inner { ... } 
} 
+0

不要你的意思'對象我的O擴展Outer'? – pedromss

+0

[編輯問題的例子] – fxk8y

回答

0

使用Singleton自我類型:

trait Outer { 
    def member: Inner 
    /* other methods... */ 
    trait Inner { self: Singleton => 
    def parent: Outer.this.type = Outer.this 
    /* other methods... */ 
    } 
} 

class OImpl extends Outer { 
    // Note that OImpl's subclasses can't override member this way 
    // You could also do private[this] object member0 extends Inner 
    // and override lazy val member = member0 to restore overridability 
    // The laziness of object and lazy val mean that member0 won't be created 
    // if a subclass doesn't use it. 
    override object member extends Inner { 
    // ... 
    } 
    // ... 
} 
+0

你是否覆蓋了一個對象的方法?順便說一句。 Singleton對我來說是新事物,但在閱讀文檔後,這似乎是正確的。要測試它的時候了.. – fxk8y

+0

@HTNW 如果我們這樣做'私人[這]對象member0延伸Inner'那麼編譯器說: 「錯誤:私有對象member0逃脫它的定義範圍類型OImpl.this.member0的一部分。類型」。 –

+1

@DmytroMitin這是因爲類型推斷。這樣做推斷'member:member0.type',但'member0'不能在'OImpl'之外轉義。明確指定一個類型爲'member:Inner = member0'。 – HTNW