我做错了什么? (使用Scala的超类参数)

发布于 2024-11-28 18:37:54 字数 1309 浏览 2 评论 0原文

我有一个家长班和几个孩子班。我想要的是,当在子类的实例上调用特定的 setter 方法时,父类中“同步”的布尔值将设置为 false。应该可以在同步或非同步状态下创建子类。

这就是我的想法:

class A(protected var isSync: Boolean) {
}
class B(var value:String, isSync: Boolean) extends A(isSync) {
  override def value_=(value:String): Unit = {
    this.isSync = false
    this.value = value
  }
}

现在,由于多种原因,它无法编译:将 value 分配给 this.value 不明确; var 注释已经定义了 value_=this.isSync 引用本地构造函数字段 isSync,而不是(可写)父字段。

Stack Overflow 上的 这个问题指出我应该使用 __value (或任何不是 value 的名称)作为构造函数中的 private var,并自己定义 setter。经过一番修改后,我想出了以下可以编译并运行的代码:

class A(protected var isSync: Boolean) {
}
class B(private var __value: String, private val __isSync: Boolean)
    extends A(__isSync) {
  def value = __value
  def value_=(value: String) = {
    this.isSync  = false
    this.__value = value
  }
}

然而,这段代码感觉太腐烂了,以至于现在我怀疑我犯了一个(如果不是更多的话)根本性错误。有人可以纠正我吗?

因此,具体问题是:

  1. 我正在尝试实现的内容是否存在(以及是否存在)根本缺陷?对于某些上下文:对象在更改时可以(并且可能必须)与服务器同步。
  2. 将参数传递给您扩展的类的正确/最佳方法是什么?
  3. 覆盖 var 生成的 setter 的正确/最佳方法是什么(或者通常提供您自己的 setter 实现)?

I have an parent class, and several child classes. What I want is when specific setter methods are called on instances of the child classes, a boolean value for "is synchronized" in the parent class is set to false. It should be possible to create child classes in either a synchronized or an unsynchronized state.

This is what I came up with:

class A(protected var isSync: Boolean) {
}
class B(var value:String, isSync: Boolean) extends A(isSync) {
  override def value_=(value:String): Unit = {
    this.isSync = false
    this.value = value
  }
}

Now, this doesn't compile for a number of reasons: the assignment of value to this.value is ambiguous; the var annotation already defines value_=; and this.isSync references the local constructor field isSync, instead of the (writable) parent field.

This question on Stack Overflow pointed out that I should use __value (or any name that isn't value) as a private var in the constructor, and define the setter myself. After some more tinkering, I came up with the following code that compiles and works:

class A(protected var isSync: Boolean) {
}
class B(private var __value: String, private val __isSync: Boolean)
    extends A(__isSync) {
  def value = __value
  def value_=(value: String) = {
    this.isSync  = false
    this.__value = value
  }
}

However, this code feels so rancid that by now I suspect I'm making a (if not more) fundamental mistake. Could anyone please correct me?

Thus the concrete questions are:

  1. Are there (and if, which) fundamental flaws in what I'm trying to implement? For some context: the objects, when changed, can (and probably have to) be synchronized with a server.
  2. What is the right/best way to pass parameters to a class you extend?
  3. What is the right/best way to override the setter generated by var (or generally provide your own setter implementation)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

倾听心声的旋律 2024-12-05 18:37:54

关于问题1:我猜您想跟踪对象自上次复制到服务器以来是否已更改,不是吗?这是明智的,只要服务器上的副本不能被修改:否则确保副本的一致性会更加复杂(副本一致性是谷歌搜索的关键字,但我不推荐它)。
为了清楚起见,我会谈论干净或肮脏 - synchronized 让我想起了 synchronized Java 语句。

关于问题2,您不需要将__isSync设为private val(它将存储在类中),您可以将其保留为构造函数参数。只要不使用它(除了在 A 的构造函数的调用中),__isSync 就不应该在 B 的实例中占用额外的空间。我在那里删除了 private val 注释,获得按预期正确编译的代码。

class A(protected var isSync: Boolean) {
}
class B(private var __value: String, __isSync: Boolean)
    extends A(__isSync) {
  def value = __value
  def value_=(value: String) = {
    this.isSync  = false
    this.__value = value
  }
}

关于美观和问题 3:我会简单地避免使用双下划线。 《Scala 编程》(第 18.2 节)中的类似示例只是使用较短的名称。他们还使用 private[this] 来防止同一类的其他实例访问该成员。最后,您可以在类 decl 后删除 {}。在此示例中(即使可能不在您的代码中)。

因此我们会得到这样的代码,它与我已经提到的示例很接近:

class A(protected var isSync: Boolean)
class B(private[this] var v: String, sync: Boolean)
    extends A(sync) {
  def value = v
  def value_=(value: String) = {
    isSync  = false
    v = value
  }
}

About question 1: I guess that you want to track whether the object has been changed since last time it was copied to the server, don't you? That's sensible, as long as the copy on the server cannot be modified: otherwise ensuring consistency of the replica is more complex (replica consistency is the keyword for googling, but I wouldn't recommend it).
For clarity, I would talking about being clean or dirty - synchronized reminds me too closely of the synchronized Java statement.

About question 2, you don't need to make __isSync a private val (which will be stored in the class), you can leave it as a constructor parameter. As long as it is not used (other than in the invocation of A's constructor) __isSync should not take additional space in instances of B. I removed the private val annotation there, obtaining this code which compiles correctly as expected.

class A(protected var isSync: Boolean) {
}
class B(private var __value: String, __isSync: Boolean)
    extends A(__isSync) {
  def value = __value
  def value_=(value: String) = {
    this.isSync  = false
    this.__value = value
  }
}

About aesthetics and question 3: I would simply avoid the double underscore. Similar examples from Programming in Scala (Sec 18.2) simply use shorter names. They also use private[this] to prevent access to the member from other instances of the same class. Finally, you can remove {} after the class decl. in this example (even if maybe not in your code).

Thus we'd get code like this, which is close to the examples I already mentioned:

class A(protected var isSync: Boolean)
class B(private[this] var v: String, sync: Boolean)
    extends A(sync) {
  def value = v
  def value_=(value: String) = {
    isSync  = false
    v = value
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文