我发现很多程序,都喜欢在class中定义private变量,但又另外提供get,set,函数. 
我认为这样写太麻烦,还不用直接定义public变量. 访问的时候直接 class实例.变量名, 请问这样做好吗?

解决方案 »

  1.   

    通过bean方法来改变变量的值比较安全,这样你可以很方便的知道这个值在什么地方被改变了。而且在改变的时候加上其他处理,如print也方便
      

  2.   

    这样不好,楼主需要查一下JavaBean,而且,这样getX/setX其实不麻烦,可以用IDE自动生成,100个也就几秒钟
      

  3.   

    Give you an example. Let's say you have class A and B as follows.
    -----------------------------------------------------
    public class A {
        public int numberA;
    }public class B {
        public A a;
        public int numberB;    public B() {
            a = new A();
            numberB = 0;
        }    public int someMethod() {
            return numberB / a.numberA;
        }
    }
    ------------------------------------------Then someone else is using your compiled class files.
    -----------------------------------------------------
    public class C {
        public static void main(String[] args) {
            B b = new B();
            b.numberB = 10;
            b.a.numberA = 0;
            b.someMethod();
        }
    }
    -------------------------------------------Then this guy complain that your program has problems. What can you do?
      

  4.   

    Alternatively, we have the following.
    --------------------------------------------------------
    public class A {
        private int numberA;
        public getNumberA() {
            return this.numberA;
        }
        public void setNumberA(int number) {
            if (number > 0)
                 this.numberA = number;
        }
    }
    ----------------------------------------------------
    Your program is protected (although very much limited in the example).You'd better read materials about OO Encapsulation to study further.
      

  5.   

    定义了Public变量,就跟让你把钱拿出来放到大家面前,---想怎么花就怎么花
      

  6.   

    规范化, 一些组件调用时会通过设置器(setXXX) 来设定变量值.
      

  7.   

    1.这个是有好处地,虽然好处说不太清楚;(但是,请乖乖的照做~听姐姐话,有糖吃:P)
    2.IDE可以帮你生成的,一点都不麻烦地!!(选中变量,右键选source-->Generate Getters and Setters...)
      

  8.   

    我就看不出直接定义public有什么问题,访问起来效率肯定比定义getx setx 快.
      

  9.   

    封装特性。。
    java的特点。。
      

  10.   

    大家都说封装,
    我感觉,这主要是java的风格吧.类库里面基本上没有直接调用一个共有变量的.全都是用get/set
    C#的类库里面多数都是使用共有变量来存取的.可能是因为两种语言的访问器不同的原因吧.
      

  11.   

    有些人说安全性,好象没什么依据, 请问我使用public变量有什么不安全? 使用get 与 set 安全在哪里?? 有些人说封装性,如果你把一个变量理解为类的一个属性(其它语言就是这样的), 那么变量本身就是封装在类内面的.我只知道用get 与 set 有一个好处, 当输入.get(.set) 时就能显示所有的属性. 把所有设置都归纳起来,对于外部的使用都方便而已. 假如你开发一个类给别人用,人家只要输入.get就能知道所有的属性.个人认为用get 与 set 只是一种规范做法而已,完全等效于public变量, 与安全性,封装性无关系
      

  12.   

    1.0的时候,很多都是public,后来sun都改成了get,set
      

  13.   

    get()和set()看你怎么用了,如果里面只放一个赋值语句的话,是和public变量没什么区别。
    但是设想,你有一个Person类代表一个人,Person有一个char类型的sex字段表示性别,理论上,sex只接受两个值,'M'和'F',但如果你把sex字段设为public,你很难限制你的用户只给它赋'M'或'F'值。将sex设为private,再用setSex()来设置性别,你就完全可以控制这种行为了。
      

  14.   

    楼上有道理,而且你还可以控制只能get不能set,或相反,但如果是public就不行了
      

  15.   

    get()和set()看你怎么用了,如果里面只放一个赋值语句的话,是和public变量没什么区别。
    ======================================
    我现在只是讨论这种情况! 类似楼上说的sex 性别这种属性,当然要用set 方法来控制了.
      

  16.   

    看一下这个情况吧。
    class A
    {
        public string sex;
    }
    class B
    {
        private string sex;
        public string getSex(){return this.sex};
        public void setSex(string sex)
        {
          if(sex.equals("man") || sex.equals("female"))
            this.sex=sex;
          else
            throw new Exception();
        };
    }在使用getX setX的时候,我们可以对设置的值进行进一步的判断,如果直接使用public 就不可以进行这样的安全性控制。
    别外有一点属性我们可能并不希望其他用户对我们的属性进行写操作,这个时候,可以直接不写setX方法。这就是只读属性了。
    同样用public也是无法做到的。最后setX getX是JavaBean的规范,有很多框架(如spring hibernate 等)都是通过getX setX来对属性进行访问。一般情况下getX setX都可以通过IDE直接生成,并不麻烦。
      

  17.   

    -----------------------------------
    我现在只是讨论这种情况! 
    -----------------------------------I服了U!!好,你现在只讨论这种情况。你把所有变量都设为public,然后发布了你的代码。一段时间后,你发现你该对你的变量设置做一些控制了,然后你再通知用你的代码的所有人,“同志们,请用set()和get()来访问我的变量”,估计你会被海扁的。
      

  18.   

    我讨论的只是一般的情况,get 与 set 只用一条语句的情况. 楼上的英文回答的朋友,只是特殊情况下,用set方法控制变量,这种情况我非常理解的. 我现在写代码时候有些类定义了比较多的变量, 每个都要get,set,觉得很麻烦,而且class代码也增加了不少,不如直接public访问啦. 
      

  19.   

    也不一定都要用到get,set方法了,你可以只取其中之一或者都不要也可以,但是不建议直接用public 变量来访问,不够安全,而且也最好养成好的习惯
    就像那些编码规范一样,你不遵守你的代码还是一样能用
      

  20.   

    谢谢大家.
    大概明白get与set 的好处了. Dan1980() 说的有道理. 用get与set 方便以后扩展功能.  某个变量以后说不定就会要求有什么限制了,这时候我们只要修改set函数即可.
      

  21.   

    楼主,你在这点概念和规范都理解不了,建议你不要学JAVA了
      

  22.   

    对阿,封装性,安全性!这也是选择java的原因,虽然自己学的很差
      

  23.   

    当你做大系统的时候就明白了。
    -----------------------------------
    到这个境界也就不问这个问题了
    oop
      

  24.   

    我看这里大部分人都是人云亦云,说什么安全性,封装性,只要学java的人都会说,没有一本java的书不提及这些名词, 其实真正理解的人不多.
      

  25.   

    用了getter and setter就好比给你的变量戴了个套 所以安全许多!
      

  26.   

    cxzhq2002(清风) ( ) 信誉:100    Blog  2007-1-8 19:00:36  得分: 0  
     
     
       
    数据与行为相分离 
     
    =====================================================================
    没错,这个是OO的基本概念。顺便说一句,在一些对面向对象支持更好的语言中,例如Ruby,数据天生就是私有的,只能通过接口方法去访问。
    另外,很多IDE都支持对变量自动产生getter和setter方法,你只需要点几下鼠标,例如Eclipse.
      

  27.   

    楼主的问题特别好, 楼主的固执其实进一步引导大家更加深入地去思考这样一个看似简单而且大家都在按照做一个问题,我想肯定有许多人不能立马回答出楼主的问题的实质,回答之前都进行了思考,思考就是在学习在进步.....大家应该感谢楼主
    我对这个问题的看法: 我们不能单纯地从实现的角度去考虑这个问题,因为条条大路通罗马,但肯定付出不相同的,我们应该提升我们的编程思想(这也正是程序员coder所缺泛的),楼主所说的问题是一个典型的面象对象思想中的封装性,而非java所特有,所有面象对象的语言都应该对自己的属性进行(set/get),面向对象,看什么是对象? 对象就是属性+行为,封装就是把对象的私有属性封装起来,只有通过自己公开的行为去改变(获得)对象内部的私有属性信息,而那些public的方法正是面其它对向的接口,你只有通过接口去改变(获得)对象的私有属性
      

  28.   

    我们在设计类,或着作com组件时经常告诉其实coder,你只需要调用我的XX接口方法就可以了,内部我是怎么实现的,你不用管, 只不过你的内部实现更为复杂,而不象get/set方法那样简单, 所以就产生了楼主的疑问, 如果面向特定的环境特定的时间段,直接将属性声明为public,让外部对象访问也未偿不可, 没有面象对象思想时,我在写C语言程序时结构中的变量是可以随意被访问的,因为没有pulbic,private之分,现在我们是面向对象编程,我们需要在接口处作文章,而保护对象的私有属性,即安全性,只有通过对外公开的接口方法去访问在面向对象理论上认为是安全的。
      

  29.   

    z_lping(Schemer) ,Dan1980() 两位用鲜明的实例证明了封装性的好处所在
      

  30.   

    特别谢谢 IFindit 及 Dan1980! 
    规范做法其实我懂,所有写java程序的人都懂,但我们应该要思考为什么要这样做? 这样做的好处是什么?  你不去思考就成了机器人吧, 都老是跟着别人去做,那别指望能有创新思想了.
      

  31.   

    TO lz,JavaBean的规范看过了没有,我们平时用到的90%的framework/library都会用到javabean。比如JSP中用到的useBean,TagLib,Struts中用到的ActionForm、Beanutils、Degister。这些基于JavaBean的,只认get/set/isXxx(即使class里面根本就没有xxx)
      

  32.   

    z_lping(Schemer)纠正一点.现在的java中,0可以作分母.
    java 5.0中
    java.lang.Double:
    line:38:
        public static final double POSITIVE_INFINITY = 1.0 / 0.0;
    line:45:
        public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
    line:52:
        public static final double NaN = 0.0d / 0.0;
    你也可以在5.0的环境下试试sysout(10 / 0)看看输出的是什么.以上是细节问题.回lz.set/get方法看似只是一个规范.但规范有规范的目的.你这里没有用.但是对实力化你的类,调用你的方法/属性的类很可能是必要的.set/get方法做规范的目的其实不是那么简单.上面很多人已经说了.但是可能你现在还没有体验到.面向对象的基本思想,封装性,安全性,稳定性,可扩展性,是否便于维护等等等等.需要完全弄清楚这些不是一天的事情.也不会一个帖子的问题.(其实我也不能完全弄清.但我已经看到了这么作的必要性.)其实很多时候不需要马上弄清楚问题的根源.不然等到你能用java开发出东西的时候大概已经很多年过去了.电脑上的任何问题如果一定要追到根源,只能用机器码解释.这完全没有必要.你想要的答案在将来你的应用中会慢慢了解.一个朋友的话:"程序员是熟练工种,不是技术工种."有一定道理.
      

  33.   

    其实是对于某些private型的数据,不能让随便什么类都能修改,如果某些类想修改,只有通过set方法来实现.如果程序是你一个人写的话,你不会有什么失误,但是如果是一个团队共同开发的程序,你定义了一个public,可能被别人误用,造成损失.
      

  34.   

    z_lping(Schemer)纠正一点.现在的java中,0可以作分母.
    java 5.0中
    java.lang.Double:
    line:38:
    public static final double POSITIVE_INFINITY = 1.0 / 0.0;
    line:45:
    public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
    line:52:
    public static final double NaN = 0.0d / 0.0;
    你也可以在5.0的环境下试试sysout(10 / 0)看看输出的是什么.=======================since jdk 1.0,所以任何JDK版本都可以
      

  35.   

    vitren兄弟,俺的例子是Integer Division而已。
      

  36.   

    还有,如果以“学院派”的角度,去思考问题,我们都应该用obj.foo()而不是obj.x = ...这样的方式,x是obj自己的属性,就应当由其自身维护,而不是我们来负责维护,此外,如果从代码维护的角度obj.foo()也比obj.x好,考虑一下,假如需要对这部分功能进行改进,或者重写,写foo()调用的方式,你只需要维护一处代码或者使用override,而obj.x的方式,就需要维护N处
      

  37.   

    如果只是把这个class当作一种组合的数据类型,完全可以直接使用public变量,使用get/set说明了这个class不止是储存数据这么简单,还可能进行一些操作,而这些操作会影响或使用到这个变量。
    一概否定public形式的变量访问方式就和一概否定goto在程序编写中的出现一样可笑
      

  38.   

    告诉大家一个好消息:Java 7准备支持property了,比如:
    public property String name;
    public readonly property String name;
    等等。
    看看javalobby上的讨论:
    http://www.javalobby.org/java/forums/t88090.html
    这是java 7 feature预览稿:
    http://blogs.sun.com/dannycoward/resource/Java7Overview_Prague_JUG.pdf
      

  39.   

    DarknessTM(我的缘分在哪里?) ( ) 信誉:100    Blog  2007-01-09 11:42:27  得分: 0  
     
     
       如果只是把这个class当作一种组合的数据类型,完全可以直接使用public变量,使用get/set说明了这个class不止是储存数据这么简单,还可能进行一些操作,而这些操作会影响或使用到这个变量。
    一概否定public形式的变量访问方式就和一概否定goto在程序编写中的出现一样可笑 
    ===========================================================================
    可笑吗? 许多对面向对象支持更好的语言就是这样做的.例如Ruby,实例变量都是私有的,只能通过接口方法访问。
      

  40.   

    ?!IMHO,对这种不会提升任何速度(编码get/set都自动生成、编译复杂度提升、运行速度不会有大的帮助)的东西不用也罢
      

  41.   

    告诉大家一个好消息:Java 7准备支持property了,比如:
    public property String name;
    public readonly property String name;
    ======================================
    哈哈,我就是想要这种效果!  不知有些自以为自己很理解oop的人怎么看. 
      

  42.   

    但,无论如何,用get,set是一种好的做法, 这点从楼上一些网友的议论中已经提过了. 
      

  43.   

    告诉大家一个好消息:Java 7准备支持property了,比如:
    public property String name;
    public readonly property String name;
    ======================================
    哈哈,我就是想要这种效果! 不知有些自以为自己很理解oop的人怎么看.==========================================================搞错没有?这也不能替代setter啊。加了个只读,只写功能而已。
      

  44.   

    他是说的类似DELPHI中的property属性, 根据需要可以在属性后加上read,write 及相应的读写函数, 其实就是直接把set/get函数加在了属性声明的后面
      

  45.   

    TO:hyqryq(不知道叫什么好) 
    如果public变量毫无用处,干脆语言设计的时候取消这个特性好了,规定不能有public的成员变量,可是目前为止有这种程序设计语言吗?
      

  46.   

    property 这种类型早在VB,Delphi,C#等中出现了,JAVA也太迟了
      

  47.   

    不好意思,没看仔细,看真有RUBY这种语言,不过是脚本语言,与一般的言语还是有一点点区别,不足于证明Public成员变量无用,其实否定了public成员变量,也就是否定了C/C++的struct关键字
      

  48.   

    如果是在Android开发,或者在内存、性能敏感的嵌入式设备上,哪个更好呢?
      

  49.   

    有些加get set 有些不必要的不加,看实际代码逻辑,就这样,