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

时间:2018-11-13 23:09:19

标签: java

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

还是直接设置变量是一种好习惯,因为可以将构造函数视为一种变种?

4 个答案:

答案 0 :(得分:7)

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

构造函数构造定义它的特定类。初始化字段是它的工作,因为-嗯-没有别的了。

保证初始化字段的唯一方法是分配它们。如果您致电二传手,则有可能被覆盖,并且可能会做其他事情。它可能会调用尚未初始化的子类中的方法。

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

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

答案 1 :(得分:2)

这取决于您是否打算对此类进行子类化,是否应该有人可以对您的类进行子类化?

  • 如果答案是否定的,您可以使用它,但我会说是 通常出于种种原因,这样做是一种不好的做法,如果您没有明确禁止继承,则可以将此类作为子类,并且重写的方法请参见下面的引用。通常,优良作法是尽可能地保持不变,使用getters / setters可以避免这样做。我还要指出,构造函数应仅具有将类初始化为有效状态所需的参数。如果也可以使用setter传递它们,则对于实现有效状态可能不是必需的。
  • 如果您想在设计类时考虑继承,那么答案是否定的;如果您使用init方法,则它既不能使用getters / setter方法,也不能使用任何可以覆盖的方法。 有效Java 2nd Edition的直接报价:
  

班级还必须遵守一些其他限制   遗产。 构造函数不得调用可覆盖的方法,   直接或间接。如果您违反此规则,程序将失败   结果。超类构造函数在子类之前运行   构造函数,因此子类中的重写方法将被调用   在子类构造函数运行之前。如果覆盖方法   取决于子类构造函数执行的任何初始化,   该方法将无法达到预期的效果。

答案 2 :(得分:0)

否,拥有访问器和更改器的目的是能够访问同一程序包中另一个类的私有字段。

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

是的,您应该直接将所需的值直接分配给变量。

答案 3 :(得分:0)

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

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
  }
}