繁体   English   中英

我应该在构造函数中使用 getter 和 setter 吗?

[英]Should I use getters and setters in constructors?

在初始化一个类时,在构造函数中使用 getter 和 setter 函数是一种好习惯吗?

或者直接设置变量是一个好习惯,因为构造函数可以被认为是一种mutator?

您不应从构造函数调用 getter 和 setter。

构造函数构造在其中定义它的特定类。 初始化字段是它的工作,因为 - 好吧 - 没有其他东西。

保证初始化字段的唯一方法是分配它们。 如果你调用一个 setter,它有可能被覆盖,它可能会做其他事情。 它可能会调用尚未初始化的子类中的方法。

如果您只是从同一个类中获取一个字段,那么调用 getter 也是一个坏主意。 如果它已在超类中声明,您可能会证明它是合理的; 如果您需要从子类中的超类获取数据,则必须调用 getter(除非它受到保护)。 如果您需要在构造期间将数据从子类传递到超类,则应将其作为参数传递。 但这与您所描述的用例不同,并且子类可能没有与 getter 相对应的自己的字段。

如果您有任何“特殊”初始化代码,请将其放在单独的私有方法中,并分别从构造函数和 setter 调用它。

这取决于,您是否打算对这个类进行子类化,其他人是否可以对您的类进行子类化?

  • 如果答案是否定的,那么您可以使用它,但我会说出于多种原因这样做通常是不好的做法,如果您没有明确禁止继承,那么可以对类进行子类化并覆盖方法,请参见下面的引用。 一般来说,以尽可能多的不变性为目标是一种很好的做法,并且使用 getter/setter 可以防止你这样做。 我还认为构造函数应该只具有将类初始化为有效状态所必需的参数。 如果它们也可以使用 setter 传入,那么它们可能不是实现有效状态所必需的。
  • 如果你想在设计你的类时考虑到继承,那么答案是否定的,如果你使用 init 方法,它也不能使用 getter/setter,或者任何可以被覆盖的方法。 直接引用 Effective Java 2nd Edition:

为了允许继承,类必须遵守更多的限制。 构造函数不得直接或间接调用可覆盖的方法 如果违反此规则,将导致程序失败。 超类构造函数在子类构造函数之前运行,因此子类中的覆盖方法将在子类构造函数运行之前被调用。 如果覆盖方法依赖于子类构造函数执行的任何初始化,则该方法将不会按预期运行。

我的看法是,当构造函数定义类时,我可以使用 setter 来检查参数和/或将它们初始化为某些值。 在我有一个计算变量的情况下,我也可以使用 getter,但我应该非常注意语句的顺序(不建议使用容易出错)。

JavaScript 中的示例:

class Point {
  constructor (x, y) {
    this.x = x.x || x // invokes the setter
    this.y = x.y || y
  }
  toString () {
    return `The point is (${this.x}, ${this.y})` // invokes the getters
  }
  set x (newX) { // I think it should be better use 'newX' as a parameter than 'x'
    if (newX > 100) {
      console.log(`The x (${newX}) value must be < 100, `, 'x set to 0')
      this._x = 0 // if we use 'this.x' here, we will get an error (stack overflow)
      return
    }
    this._x = newX
  }
  get x () { // no one but the getter and setter should know '_x' exists
    return this._x // it has to be coherent with the setter
  }
  set y (newY) {
    if (newY > 100) {
      console.log(`The y (${newY}) value must be < 100, `, 'y set to 0')
      this._y = 0
      return
    }
    this._y = newY
  }
  get y () {
    return this._y
  }
}

不,拥有访问器和修改器的目的是能够从同一个包中的另一个类访问私有字段。

从技术上讲,您可以,但是从构造函数中改变变量会破坏初始化的目的。 访问变量只是添加一个额外的步骤来获取其内容。

所以是的,你应该直接将你想要的值重新分配给你的变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM