2012-12-26 77 views
1

我试图定义一个特质C延伸部分性状AB,...所有特质,CAB,...实现一个共同的特点T。特质C应该通过调用T的实现在AB实施T,..:斯卡拉性状和名称冲突的抽象类型

trait T{ 
    def f() 
} 
trait A extends T{ 
    def f(){ 
    print("A") 
    } 
} 
trait B extends T{ 
    def f(){ 
    print("B") 
    } 
} 

特质C的期望的行为如下:

val x=new A with B with C[A,B]{} 
x.f() 
// should produce output 
A 
B 

这里我试图定义性状C,这给编译错误:

trait C[A<:T,B<:T] extends T{ 
    self:A with B => 
    override def f(){ 
    // error: A does not name a parent class of trait C 
    super[A].f() 
    // error: B does not name a parent class of trait C 
    super[B].f() 
    } 
} 

我需要拨打C方法A.f()B.f()。 有没有解决这个问题的方法?

回答

2

如果你想提供一种方式的特征内部,而且也保证了子类实现的定义,就可以告诉这个编译器与abstract override组合:

trait T { 
    def f() 
} 
trait A extends T { 
    abstract override def f() { 
    super.f() 
    print("A") 
    } 
} 
trait B extends T { 
    abstract override def f() { 
    super.f() 
    print("B") 
    } 
} 

trait C extends T { 
    override def f() { 
    // do your work here ... 
    } 
} 

val x = new C with A with B 
x.f() 

呼叫在未来实现在混合层级中,您必须在abstract override方法调用中添加一个super.f()调用。因为这样的超级调用需要现有的实现,所以需要创建的第一件事是C的实例,其混合了AB。如果混入C,AB,编译器会抱怨,因为mixin层次结构是从左到右执行的,因此无法看到C的实现。