避免在scala中继承方法

use*_*423 3 inheritance scala

以下代码段

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

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

val x = new A with B
Run Code Online (Sandbox Code Playgroud)

不编译,因为

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
Run Code Online (Sandbox Code Playgroud)

但是,我的意图是定义x,以便:

x.foo => "A.foo"
x.bar => "B.par"
Run Code Online (Sandbox Code Playgroud)

也就是说,我只希望x从B继承bar,但不是foo.scala有没有办法实现这一目标?

Deb*_*ski 12

scala> val x = new A with B { override def foo = super[A].foo }
x: A with B = $anon$1@4822f558

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

scala> x.bar
res1: java.lang.String = B.bar
Run Code Online (Sandbox Code Playgroud)

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


Rus*_*ell 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"
Run Code Online (Sandbox Code Playgroud)

或者,如果你需要一个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"
Run Code Online (Sandbox Code Playgroud)