【问题标题】:Extend trait with private constructor parameter使用私有构造函数参数扩展特征
【发布时间】:2017-01-27 19:36:00
【问题描述】:

在 Scala 中,如何使用 trait 中定义的 private 构造函数参数在类中扩展 trait?

trait Parent {
  protected def name: String
  require(name != "", "wooo problem!")
}

class Child(private val name: String) extends Parent {
  println("name is " + name)
}

上面的类报错:

类 Child 需要是抽象的,因为类型 ⇒ String 的 trait Parent 中的方法名称未定义。

当然可以:

  1. Child 类抽象化,
  2. 定义它而不使用构造函数中的私有,如class Child(val name: String)
  3. 将 Parent 设为 abstract class 而不是 trait

但是通过上述实现,我无法在扩展 trait 的同时拥有 private 构造函数参数吗?请注意,我希望变量是私有的,这样我就不能执行childInstance.name

【问题讨论】:

  • 你想用这个实现什么?为什么需要带有私有变量的构造函数?你不能只在类中定义私有变量并有一个空的构造函数吗?
  • 由于这个类被几个孩子扩展,我不想重复代码。我想我找到了一种方法。如果我在特征protected 中创建变量并将子构造函数更改为Child(name: String),我无法访问外部变量。这对我来说已经足够了!
  • 你为什么不直接定义class Child{ private val name = "" }
  • 那是因为我希望所有孩子都定义的特征中有一些方法签名。所以在我看来,一个特质更有意义!让我知道我是否错了。抱歉,我应该在问题中提到这一点。

标签: scala traits


【解决方案1】:

试试这个

  trait Parent {
    protected def name: String
    require(name != "", "wooo problem!")
  }

  class Child(override protected val name: String) extends Parent {
    val publicVar = "Hello World"
    println("name is " + name)
  }

  def main(args: Array[String]): Unit = {
    val child = new Child("John Doe")
    println(child.publicVar)
    println(child.name) // Does not compile
  }

您将无法访问 child.name

【讨论】:

  • 正如我在问题中提到的,我需要将变量设为 private。所以不,我不想使用override
  • 我将两者都更改为受保护。当我将 child 更改为 private 时,它​​不再起作用。错误消息:类 Child 需要是抽象的,因为类型 => String 的 trait Parent 中的方法名称未定义
  • 我再次更新了代码。我认为该示例可以满足您的要求: println(child.name) // 不编译
  • 感谢您的帮助!正如我在问题下方的评论中提到的那样,我找到了一种方法。与您正在做的类似,除了我不需要在子构造函数中使用override protected val
【解决方案2】:

如果您在特征中有抽象方法,则所有派生类都需要为抽象方法具有相同(或更宽松)的修饰符(在您的情况下至少受保护)。

trait Parent {
  protected def name: String
  require(name != "", "wooo problem!")
}

class Child(private val privateName: String) extends Parent {
  override protected def name: String = privateName
  println("name is " + name)
}

您可以将构造函数保持私有,但您需要定义override protected def name: String 并使用构造函数的私有值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 2016-10-22
    相关资源
    最近更新 更多