Scala:对不一定受到尊重的字段的约束

时间:2012-12-04 11:19:52

标签: scala constraints field

给我一​​些帮助,我无法解决这个问题。 如何确保始终遵守对getter方法的约束? 我的课程有这样的形式:

abstract class Element {
  var name: String
  var description: String
}

class Component (var name: String, var description: String) extends Element

出于我的项目的目的,我需要使用var。 我想在必须始终遵守的字段name上设置约束。 当我创建Component的实例时,如下所示:

val C1 = new Component ("C1 Component", "Description of C1")

当我更改值时:

C1.name = "new value"

如果我以这种方式创建类:

abstract class Element {
  protected var _name : String
  // Getter
  final def name = _name
  // Setter
  final def name_= (value:String):Unit =
    if (value.size < 5) println ("ERROR: Bad Value")
    else _name = value

  var description: String
}

class Component (protected var _name : String, var description: String) extends Element

在main方法中,因为我没有控制权:

val C1 = new Component ("C1", "Description of C1")

但是稍后,当我更改值时:

C1.name = "comp"

我希望我的吸气者永远受到尊重。 我该怎么做?

2 个答案:

答案 0 :(得分:2)

class Component (_name : String, var description: String) extends Element {
  this.name = _name
}

另外,将var _name设为私有,因此如果不使用setter,子类就无法设置它。

答案 1 :(得分:1)

在Scala中,整个类体构成了主要的构造函数。因此,您可以将setter称为构造函数的第一部分。然而,语法在我看来相当混乱。你可以这样做:

abstract class Element {
 var name: String
 var description: String
}

class Component (private var _name :String, var description : String) extends Element {
  name = _name
  def name = _name
  def name_=(value: String) = {
    require(value.size > 5, "Bad value")
    _name = value
  }
}

<强>然而即可。以你使用它们的方式vars可能是......不明智的。使用不可变类并处理此类的副本要好得多。因此,每当您需要修改该名称字段时......只需创建一个与旧名称相同的新Component组件,并使用不同的名称。有很多方法可以实现这一点(搜索镜头),但一种简单的方法是使用copy上提供的case classes方法。这是一个例子:

我们将Component类更改为案例类:

case class Component (private var _name :String, var description : String) extends Element {
  name = _name
  def name = _name
  def name_=(value: String) = {
    require(value.size > 5, "Bad value")
    _name = value
  }
}

我们的用法如下:

val C1 = new Component ("Some component name", "Description of C1") 
//Component(Some component name, Description of C1)

val C2 = C1.copy(_name = "Another component name") 
// Component(Another component name ,Description of C1)