2017-09-02 32 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