【问题标题】:Extending a trait by an object通过对象扩展特征
【发布时间】:2014-07-04 11:39:23
【问题描述】:

我有一个名为 A 的类,它扩展了一个特征 X。 X 有一个抽象变量 x 已在类 A 中实现。类 A 使用 Trait 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 使其可以使用特征X 中定义的函数foo?

【问题讨论】:

  • 你应该解释你真正想要完成的事情(你真正的问题,而不是它的抽象)。可能有一个简单的解决方案,但很难说我们是否真的不知道您要做什么。

标签: scala inheritance traits


【解决方案1】:

编译器的行为应有尽有。可能有两件事: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 = {}
}

【讨论】:

  • 嗯,我可以将函数 foo 放在一个对象中,但是我将如何确保只有类 A(及其单例对象 A)可以访问它?
  • 嗯我不确定。
【解决方案2】:

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

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

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

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


另一方面,如果你想确保x 的值在类A 和对象A 中相同,你可以在object A 中定义val x 并拉取在class A 中的那个值:

class A extends X {
  val x = X.x
  ...
}
object A extends X {
  val x = "shared-value-of-x"
  ...
}

【讨论】:

  • “事实上,从技术上讲,一个类和它的伴生对象是没有联系的;它们唯一的关系是按照惯例存在的。”不完全是:他们看到彼此的私有方法和字段。
【解决方案3】:

无论如何,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。

【讨论】:

    猜你喜欢
    • 2012-12-11
    • 2019-11-17
    • 2014-08-12
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    • 2017-11-23
    • 2015-06-03
    • 1970-01-01
    相关资源
    最近更新 更多