【问题标题】:constraints on constructor parameters构造函数参数的约束
【发布时间】:2012-11-23 17:58:52
【问题描述】:

对不起,我是 Scala 新手。 我有一个抽象类和一个从抽象类继承并实现其字段的具体类。

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

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

这是对的吗?是的? 我有许多从抽象类 Element 继承的类。 现在我想检查变量名称,我只想根据某些约束实例化名称。我把这个控件放在哪里?显然在抽象类Element中。

在 Scala 中变量声明 var x:T 等价于声明一个 getter 函数 x 和一个 setter 函数 x_=,定义如下:

def x: T
def x_= (y: T): Unit

所以我决定以这种方式声明变量,并将我的约束放在 getter 方法名称中。

abstract class Element {    
def name: String
def name_= (y: String): Unit = {CONSTRAINT}

var description: String
}

类 ConcreteElement (var name: String, var description: String) 扩展元素

这个推理正确吗? ConcreteElement 居然实现了 Element 的字段?

【问题讨论】:

  • 您的上下文中真的需要可变字段(变量)吗?
  • 有些字段是 String 类型,而有些字段是 Set(something) 类型。我认为没有必要使用var。但是如果我不使用var,我如何在方法setter上设置约束

标签: scala parameters constraints


【解决方案1】:

您的def name_= 仅在未被子类覆盖时才有效。所以我猜你需要final 来防止它被覆盖。

abstract class Element {
  protected var _name: String
  final def name: String = _name
  final def name_= (value: String) {
    if (isBadValue(value)) throw new IllegalArgumentException
    _name = value
  }
  var description: String
}
class ConcreteElement (protected var _name: String, var description: String) extends Element

【讨论】:

  • 非常感谢您的回答。对不起,但也许我不是很清楚。我有一个带有模型域的包。由抽象类和具体类组成。在另一个包中,我想实现一个 DSL 来实例化我的类。域中的某些字段具有约束。他们不能接受所有的价值观。您提出的解决方案并不能解决我的问题。我继承的_name 不会被测试。正确的?另外,如果我在不同的包中工作,我可以使用受保护的吗?
  • 您的ConcreteElement 不得覆盖namename_=,但它可以覆盖_name。并且您的其他班级不得访问_name。相反,他们必须使用namename_=
  • 您好,很抱歉,但我不明白如何覆盖。所有从 Element 继承的类都不能覆盖字段“name”,它们必须实现字段:Element 的“name”。请原谅我的英文翻译不好
  • 您好,您的解决方案仅在为新值分配名称时才控制约束。但不是在您创建一个新的 ConcreteElement 实例时。示例:在这里我无法控制:val C1 = new ConcreteElement ("nameOfC1", "descriptionOfC1") 但在这里我可以控制:C1.name = "otherName" 我想永远控制字段名称。这个问题有解决方案吗?谢谢您,给您带来的不便请见谅。
猜你喜欢
  • 1970-01-01
  • 2018-10-26
  • 2020-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 2010-12-23
相关资源
最近更新 更多