【问题标题】:Specifying method in getter/setter在 getter/setter 中指定方法
【发布时间】:2013-05-21 09:45:43
【问题描述】:

要真正理解封装的含义,必须通过类公共方法访问类私有字段的示例按照定义,但实际上它并没有什么区别,因为该字段仍然可以按原样访问。
所以,我认为在 getter/setter 内部应该有一些处理来隐藏字段的处理方式。但它打破了背后pojos的原则。这种情况怎么办?

【问题讨论】:

    标签: java encapsulation pojo


    【解决方案1】:

    我不确定您所说的“POJO 原理”是什么。下面是一个 POJO,仍然隐藏在 getter 和 setter 后面的实现细节:

    public class Example {
        private int thousands;
        private int units;
    
        public void setValue(int value) {
            thousands = value / 1000;
            units = value % 1000;
        }
    
        public int getValue() {
            return 1000 * thousands + units;
        }
    }
    

    【讨论】:

    • 通常的做法是获取/设置,其余工作由 IOC 等完成...
    • @rafiki 为什么?如果我将私有变量更改为单个整数,Example 的接口不会改变。
    • 是的,我明白了,但它使我的 POJO 的可重用性降低......例如,我不能使用我在某些功能中创建的同一个 pojo 对象来从支持对象保存/检索的数据库中检索信息,例如休眠而不是每次都创建类型或数据类型条目有些相似的新对象并以堆结束。
    • @rafiki:你什么意思? Hibernate 也尊重 getter/setter,而不是私有数据成员。
    【解决方案2】:

    封装意味着不暴露你的类的内部。

    在 Java 上下文中,这意味着您的类的属性不应被其他类访问,相反,您的类应提供允许访问属性的方法。在 POJO 类的情况下,这些方法只允许设置 (setters) 和获取 (getters) POJO 类的属性值。

    封装的目的是保护你的类的属性不被其他类修改。您的班级显然可以使用班级中的属性做任何您想做的事情。

    【讨论】:

      【解决方案3】:

      不,该字段不能按原样访问。使方法成为 getter 或 setter 所需的一切都是正确的签名。

      public String getFoo() {
        return null;
      }
      

      这是 String foo 的完美 getter,即使它返回 null

      public void setFoo(String foo) {
        // do nothing
      }
      

      这对于同一个成员来说是一个完美的设置器,即使它什么都不做。

      【讨论】:

      • 是的,但我想设置/获取,但仍然不让任何人知道我以什么形式存储信息。它可以是哈希或某些对象等。我也可以通过创建对象并将我的字段设置为 public 来直接设置它
      【解决方案4】:

      getter 和 setter 的众多用途之一是限制变量的值。通过将数据成员设为私有并保持 getter 和 setter 公开,程序员可以检查变量的值。例如:

      class Employee
      {
          private int age;
      
          public int getAge()
          {
              return this.age;
          }
      
          public void setAge(int age)
          {
              if(age<18 || age>60)
                  this.age = age;
              else
                  System.out.println("The age of the employee should be between 18 and 60");
          }
      }
      

      在这种情况下,雇员的年龄不能超过 18 岁和超过 60 岁。

      【讨论】:

        【解决方案5】:

        不知道为什么人们通常将数据封装与数据隐藏混为一谈。数据封装只是意味着将数据分组在一起,而数据隐藏是存储这些数据的一种方式,因此其他人无法知道它的内部实现。

        假设您有一个 PersonalInfo 类,其中有姓名、性别、年龄等字段。作为程序员(您是),您将为用户提供一些输入这些字段的方法,使用 setter 将它们保存在您的 PersonalInfo 对象中methods.IF 用户希望查看您简单调用 getter 的信息并显示信息。您的实现可能会将此变量存储在地图中可能会有所不同。所以你可以说

        public void setName(String name){
          SomeMap.add("name",name);
        }
        

        注意*你是程序员,你总是知道实现*n。保持字段私有是只允许您的类方法访问您的数据。

        这样想。用户可以创建一个对象。他可以使用 getter 和 setter 设置所有字段。使用 DOB(出生日期)计算年龄可能是您的实现,在这种情况下,您将不提供年龄设置器。在这种情况下,用户不能说 myObj.age=23。这纯粹是你的实现。希望这能消除混乱!

        【讨论】:

        • 是否支持 POJO 主体...不支持!
        • 我不明白你为什么要对这个 POJO 造成如此多的困惑。它只是普通的旧 java 对象,它没有像所有实例变量都必须有 getter 和 setter 那样的约束。请参考Wiki 如果您对 POJO 原理有任何参考,请在此处粘贴。
        【解决方案6】:

        它仍然可以访问,但是当你直接使用它(公共变量)时你会看到你可以不受任何限制地更改变量的值。将这种私有变量与 setter 和 getter 方法一起使用的好处是,您可以在 setter 方法中编写代码来检查值集是否在预期范围内。或者您甚至可以以不同于表观视图的形式存储该值。例如,您可以通过将偏移量添加到 setter 方法的参数值来存储变量的值,而在 getter 方法中,您可以只恢复过程(封装)。当值集不在预期范围内时,您甚至可能抛出异常。

        示例 1: 这里 var1 是一个私有变量

        public void setValue(int var1){
                 if(var1<0){
                        //throw exception
                  }
                 this.var1=var1;
         }
        

        示例2:

         public void setValue(int var1){
                this.var1=calculatesomething+var1;
        }
        public int getValue(){
                return calculatesomething+this.var1;
        }
        

        这就是封装的使用.....一切顺利

        【讨论】:

          【解决方案7】:

          封装是为了限制对类变量的访问,并规范编辑它们的方式。

          Class Test
          {
           public int a;
           public Test()
           {
            a = 0;
           }
           public getA()
           {
            return a;
           }
          
           public setA(int a)
           {
             this.a = a
           }
          }
          
          Class TestMain
          {
            main()
           {
             Test t = new Test();
             System.out.println(t.a);   // This prints 0;
             int a = t.getA();
             a = 10;
             System.out.println(t.a);   // This still prints 0;
          
             t.a = 20;
             System.out.println(t.a);   // This prints 20;
           }
          }
          

          在上面的例子中,程序员可能不是故意改变t.a的值,而是改变了值。

          如果他真的打算改变它,那么他应该使用setter。

          封装是java提供的解决某些实际问题并有助于扩展的特性。

          如果 Test 和 TestMain 类是由同一个人编写的,则不会有任何混淆。 但实际上并非如此。

          【讨论】:

          • @Sushim Mukul Dutta :在上面的例子中,我想展示直接访问实例变量的后果。在不将变量保持为公开的情况下如何解释这一点。
          • 我的错,但最好举一个具有适当封装的类的例子来说明差异。
          猜你喜欢
          • 2020-12-27
          • 2011-04-14
          • 2017-09-09
          • 2017-08-23
          • 2017-08-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多