【问题标题】:What's the point of get and set methods [duplicate]get和set方法有什么意义[重复]
【发布时间】:2014-12-11 06:26:28
【问题描述】:

在我的 CS 课程中,我只是在学习课程和 OOP。

所以当你创建一个类时,你会初始化一定数量的私有变量。

我知道您将它们设为私有,因为如果它们是公开的,它们将很容易更改并可能导致很多错误。

所以我们使用 get 和 set 方法来更改变量。但这又一次让变量很容易改变,对吧?那么首先将它们设为私有有什么意义呢?

【问题讨论】:

标签: java class oop encapsulation


【解决方案1】:

使用 getter 和 setter(称为 encapsulationdata-hiding)的一些好处:

1.类的字段可以设为只读(仅提供 getter)或只写(仅提供 setter)。这使该类可以完全控制谁可以访问/修改其字段。

例子:

class EncapsulationExample {
    private int readOnly = -1;  // this value can only be read, not altered
    private int writeOnly = 0;    // this value can only be changed, not viewed
    public int getReadOnly() {
        return readOnly;
    }
    public int setWriteOnly(int w) {
        writeOnly = w;
    }
}

2。类的用户不需要知道类实际如何存储数据。这意味着数据是独立于用户而独立存在的,因此可以更轻松地修改和维护代码。这允许维护人员进行频繁的更改,例如错误修复、设计和性能增强,同时不会影响用户。

此外,封装的资源可供每个用户统一访问,并且具有独立于用户的相同行为,因为该行为是在类内部定义的。

示例(获取值):

class EncapsulationExample {
    private int value;
    public int getValue() {     
        return value; // return the value
    }
}

现在,如果我想返回两倍的值怎么办?我可以更改我的 getter,所有使用我的示例的代码都不需要更改,并且将获得两倍的值:

class EncapsulationExample {
    private int value;
    public int getValue() {
        return value*2; // return twice the value
    }
}

3.使代码更简洁、更易读、更易于理解。

这是一个例子:

无封装:

class Box {
    int widthS; // width of the side
    int widthT; // width of the top
    // other stuff
}

// ...
Box b = new Box();
int w1 = b.widthS;  // Hm... what is widthS again? 
int w2 = b.widthT;  // Don't mistake the names. I should make sure I use the proper variable here!

带封装:

class Box {
    private int widthS; // width of the side
    private int widthT; // width of the top
    public int getSideWidth() {
        return widthS;
    }
    public int getTopWIdth() {
        return widthT;
    }
    // other stuff
}

// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!

看看在第二个示例中,您对获取的信息有多少控制权,以及这是否更清晰。请注意,这个例子是微不足道的,在现实生活中,您将处理许多不同组件访问的大量资源的类。因此,封装资源可以更清楚地了解我们正在访问哪些资源以及以何种方式(获取或设置)。

这里是 good SO thread 关于这个主题的。

这里是good read 数据封装。

【讨论】:

  • 如果你同时提供 get 和 set 并且不需要在 set 或 get 阶段操作它,我不明白你为什么要在 getter 中使用不同的名称无论如何,如您的示例所示,为什么不更改变量的真实名称。有一致的名字不是更好吗?即使您的用例非常简单并且 getter/setter 没有明显的优势,是否值得进行封装?
  • 这完全取决于特定的用例,尽管通常一致的命名通常更好。我的例子很简单,目的是在许多可能的情况下演示封装。如果您的代码中只有几个变量,那么封装可能是一种矫枉过正。
【解决方案2】:

客观:一切都是为了最佳实践!!!

1) 如有必要,使用 get 方法公开您的属性。 2)如有必要,允许使用set方法修改属性(状态修改);

同时拥有公共的 get 和 set 方法而不进行处理与拥有 public 的属性相同。

【讨论】:

    【解决方案3】:

    如上述评论所述,getter 和 setter 封装(即隐藏)类的内部细节。因此,与您交互的其他类不需要了解实现细节。

    例如,在您描述的简单情况下,实例变量通过 getter 和 setter 公开。但是,如果您想更改您的类,以便不再使用实例变量,而是将值保存到磁盘,该怎么办。您可以在不影响班级用户的情况下对班级进行此更改。

    请记住,getter 和 setter 并不总是需要提供。如果您不希望您的类提供设置或读取这些属性的方法,请不要这样做。只需将它们设为私有即可。

    【讨论】:

    • 你能再解释一下吗?我想我有点明白了,但我还没有学到很多这些东西,所以我仍然很困惑。
    • 您有什么特别想详细说明的地方吗?
    • 顺便说一句,正在提交很多好的答案。
    【解决方案4】:

    一句话,Encapsulation.setters 还允许您控制如何将值输入到您的程序中。许多像我这样的新程序员经常对这个概念感到困惑。我强烈建议你阅读this SO question

    【讨论】:

      【解决方案5】:

      传统上,它们在封装方面是合理的。通过提供对类字段的读取和写入的适度访问,我们理应减少耦合。

      用更简单的语言:通过控制其他类读取和更改我们的数据的方式,我们减少了我们类的数据可以更改的方式。这意味着减少了类之间的连接,从而降低了复杂性。

      但是,同样的逻辑表明,通常应该避免使用 getter 和 setter,除非确实需要它们,而且这种需要很少。在大多数情况下,一个类应该“倾向于自己的编织”——如果要对这个类的数据进行计算,它应该这样做。如果一个值应该改变,它应该做改变。

      例如,考虑一个空间中的对象。它有一个指定为 (x,y,z) 的位置。我们可能允许其他类随意设置它们 - 这显然是可怕的,但并不明显这些设置器会更好。您真正想要的是一个构造函数来设置初始位置,然后是影响该位置的方法 - 例如,记录冲击或加速度。然后你在做面向对象编程。

      【讨论】:

        【解决方案6】:

        Get 和 Set 方法优于“公共”变量,因为它们将类的用户与内部更改隔离开来。

        假设您有一个变量“StockQty”并将其公开,因为这似乎是最容易做的事情。

        稍后,您会收到一个用户要求,以跟踪一段时间内的库存历史。您现在需要实现一个 SetStockQty() 方法,以便在设置新数量之前将旧数量保存在某处。

        现在您班级的所有用户都必须更改代码、重新记录和重新测试。

        如果您一开始就有 SetStockQty() 方法,那么您只需要更改和测试您的代码。

        第二个原因是您可以在没有 Setter 的情况下使用 Getter,从而有效地将变量设置为“只读”。

        【讨论】:

          【解决方案7】:

          封装或数据隐藏使您可以更好地控制可以为字段设置哪些值。下面是一个示例,如果您不希望类属性具有负值:

          class WithoutGetterSetter {
             public int age;
          }
          
          class WithGetterSetter {
             private int age;
             public setAge(int age) {
                if(age < 0)
                  // don't set the value
                else 
                   this.age = age;
             }
          }
          
          
          public class testEncapslation {
             public static void main(String args[]) {
                WithoutGetterSetter withoutGetterSetter = new WithoutGetterSetter();
                withoutGetterSetter.age = -5;
          
                WithGetterSetter withGetterSetter = new WithGetterSetter();
                withGetterSetter.setAge(-5); 
             }
          }
          

          【讨论】:

          • 所以你说 get 和 set 是为了如果你想做的不仅仅是设置或获取变量,比如如果你想在获取或设置变量之前检查东西?但如果我的设置方法只是年龄=年龄,我不妨公开年龄?
          • 其他人提到的好处不止一个。
          【解决方案8】:

          get 用于获取属性的值,set 用于将值赋给属性 例如:

          private int variable;
          
          public int getVariable(){
             return variable;
          }
          
          public void setVariable(int aux){
             variable=aux;
          }
          

          一般来说,是用来封装一个属性的。

          参考:

          Set and Get Methods in java?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-15
            • 1970-01-01
            • 1970-01-01
            • 2011-04-14
            • 2013-12-26
            • 1970-01-01
            • 2021-05-27
            • 2012-06-03
            相关资源
            最近更新 更多