通过对象扩展特征

时间:2014-07-04 11:39:23

标签: scala inheritance traits

我有一个名为A的类,它扩展了特征XX有一个抽象变量x,已在类A中实现。类A使用名为X的特征foo中的一个函数。我正在努力制作一个班级A的伴侣对象并加入一些静态的'其中的方法名为Ofoo。我的问题是Ofoo使用foo。所以,我尝试过这样的事情:

trait X{
val x:String
def foo = {
    //Full implementation here
    }
}

case class A extends X{
val x = "barbaz"
// Class uses foo
}

object A extends X{
def Ofoo = {
    //This also needs to use foo
    }
}

我收到一条错误消息,指出无法实例化对象A,因为特征x中未定义变量X。 我应该如何构建A以便它可以使用特征foo中定义的函数X

3 个答案:

答案 0 :(得分:3)

编译器的行为应该如此。可以有两件事:foo使用x吗?

如果是这种情况,则需要在编译器声明的情况下声明具有x的实例。你可以说:

object A{
    def ofoo = new X{val x = "default"}.foo
}

如果foo没有使用x,那么我不确定它是否应该属于特征X。然后,您可以创建object X,然后在其中包含foo,例如:

trait X{
   val x:String
}

object X{
   def foo = {}
}

答案 1 :(得分:1)

如何在x中实施A?它只是一个对象;它必须遵守相同的规则,包括实现正在扩展的任何类/特征的抽象成员。

object A extends X {
  val x = "hello"
  ...
}

仅仅因为它是已经从class A继承并实现X的{​​{1}}的伴随对象,并不意味着x以某种方式神奇地重用它。

事实上,从技术上讲,一个阶级和它的伴侣对象没有联系;他们唯一的关系按惯例存在。


另一方面,如果您想确保object XxA的值相同,则可以定义{{1}在A中输入val x中的值:

object A

答案 2 :(得分:0)

无论如何,x必须由对象A或其超类/超类中的一个定义。

根据以前的提案和OP的回复,我假设foo不应该从其他地方访问,因此:

package pack {

  trait X{
    val x:String
  }

  // Reachable only in the same source file
  sealed trait Y extends X{

   // if foo doesn't use x below, no need to extend X, though
   private[pack] def foo = {
      //Full implementation here
      println("x = "+x)
    }
  }

  case class A() extends X with Y{
    val x = "barbaz"
    // Class uses foo
    foo
  }

  object A extends X with Y{
    val x = "barbatruc" 
    def ofoo = {
      //This also needs to use foo
      foo
    }
  }

}

实际上我很难理解OP想要什么。我同意toto2。