如何定义一个通过调用方法将参数传递给超类的对象?

时间:2014-07-23 02:37:09

标签: scala extend traits

我有一个超级班:

class P(name:String)

辅助特质:

trait SysConfig {
  def prop(key:String) = System.getProperty(key)
}

然后我想定义一个扩展P的对象:

object C extends P(prop("user.name")

它未编译,因为它无法找到prop方法。所以我with SysConfig

object C extends P(prop("user.name") with SysConfig

不幸的是,它仍然无法编译

有没有办法让它发挥作用?

2 个答案:

答案 0 :(得分:0)

arg在当前定义之外的上下文中进行评估,因此没有。

您必须将计算放在另一个对象中。

如果您正在考虑这个问题,答案也证明是否定的:

scala> class P(name: String)
defined class P

scala> trait Prop { def prop(k: String) = sys.props(k) }
defined trait Prop

scala> class C(p: String = C.prop("user.name")) extends P(p); object C extends C() with Prop
<console>:9: error: module extending its companion class cannot use default constructor arguments
       class C(p: String = C.prop("user.name")) extends P(p); object C extends C() with Prop
                                                                               ^

那是因为默认args是伴侣定义的方法。

类似地,

scala> class C(p: String) extends P(p); object C extends C(C.prop("user.name")) with Prop
<console>:9: error: super constructor cannot be passed a self reference unless parameter is declared by-name
       class C(p: String) extends P(p); object C extends C(C.prop("user.name")) with Prop
                                                           ^

答案 1 :(得分:0)

如果我不误解这个:),我认为这里有两件事是不可能的。

  1. 特质构成或可堆叠的特质总能让正确的特质获胜。在此示例中,它尝试使用左侧覆盖右侧。

  2. 当我们使用特质成分时,特质结构不会改变。我们能做的唯一灵活的事情是子特性多态性。蛋糕模式正在使用这种方式,但线性化是一个问题。但是,它与此无关。

  3. 我认为正确的方法是创建一个类/特征来执行覆盖事物

    class P(name:String)
    
    trait SysConfig {
      def prop(key:String) = System.getProperty(key)
    }
    
    class C extends P("123") with SysConfig {
      override def prop(key: String) = "123"
    }
    
    trait Foo extends P with SysConfig {
      override def prop(key: String) = "123"
    }
    
    new C