2012-04-26 84 views
3

下面的代码片段避免继承方法斯卡拉

class A { 
    def foo = "A.foo" 
} 

trait B { 
    def foo = "B.foo" 
    def bar = "B.bar" 
} 

val x = new A with B 

不编译,因为

error: overriding method foo in class A of type => java.lang.String; 
method foo in trait B of type => java.lang.String needs `override' modifier 

然而,我的本意是定义X,这样:

x.foo => "A.foo" 
x.bar => "B.par" 

也就是说,我只想要x从B继承栏,但不是foo。 scala有没有办法达到这个目的?

回答

12
scala> val x = new A with B { override def foo = super[A].foo } 
x: A with B = [email protected] 

scala> x.foo 
res0: java.lang.String = A.foo 

scala> x.bar 
res1: java.lang.String = B.bar 

这显然不是你想要经常做的事情。

+0

+1这是一个巧妙的技巧... – Russell 2012-04-26 21:36:17

+1

还要注意,虽然它可以很好地与defs一起使用,但vals会变得更加棘手。 – 2012-04-26 21:39:34

5

因为它似乎并不像你真的想A with B一个B,而是有机会获得一个B的行为的一个子集,这听起来像在继承一个很好的案例组成:

class A(val b: B) { 
    def foo = "A.foo" 
    def bar = b.bar 
} 

class B { 
    def foo = "B.foo" 
    def bar = "B.bar" 
} 

val x = new A(new B) 
x.foo => "A.foo" 
x.bar => "B.bar" 

或者,如果你需要一个A没有B的大部分时间,但有时需要能够调用bar方法就可以了,你可以用一个隐式转换做到这一点:

class A { 
    def foo = "A.foo" 
} 
class B { 
    def foo = "B.foo" 
    def bar = "B.bar" 
} 

implicit def a2b(a: A) = new B 

val x = new A 
x.foo => "A.foo" 
x.bar => "B.bar"