我们一般认为一个数据成员应该是:
class A{
private boolean flag;
}
如果其它地方也要使用这个flag。那么如何进行读取和设置呢。
直接赋值吗。还是用两个成员方法:
public void set()
public boolean get()
说实话,我觉得这两个方法与直接获得数据成员没有什么区别
class A{
private boolean flag;
}
如果其它地方也要使用这个flag。那么如何进行读取和设置呢。
直接赋值吗。还是用两个成员方法:
public void set()
public boolean get()
说实话,我觉得这两个方法与直接获得数据成员没有什么区别
封装特性封装就是将客户端不应看到的信息包裹起来。使内部执行对外部来看是一种不透明的、是一个黑箱,客户端不需要内部资源就能达到他的目的。
1.事物的内部实现细节隐藏起来
2.对外提供一致的公共的接口――间接访问隐藏数据
3.可维护性
private int age;
public int getAge(){
return age;
}
public void setAge(int value){
if(value <= 0 || age >= 150){
throw new ArgumentException ("人的年龄必须大于0且小于150");
}
this.age = value;
}
}
也就是说,用方法设置属性值,可以在返回或设置时对实例进行一步的操作,这是直接赋值做不到的另一个原因就是,用 set/get 是一种编程规范,为将来的扩展作准备,可减少模块之间的耦合。
以楼主的代码为例,如果类 A 已经这样定义好了,并且这个类也已经通过测试、发布,因为楼主的这个类写得很好,有不少同事(包括你自己在内)也在使用这个类,并且很多代码都对类A对象的 flag 属性进行了各种各样的赋值。但是过一段时间之后,由于各种原因(可能需求发生变化,也可能类中有一点小错误),类A需要在它的 flag 属性值发生变化时作一点小动作(比如向数据库插入一条记录、写一个日志等),也可能当类 A 的对象正在做一件工作时必须拒绝将它设置为 true 等等等等。所以,这时你就应该把 flag 属性设置成 private,并为它添加 get/set 的方法。然而,你的同事张三、李四、王五等人的代码中是这样使用类A的:
A a1 = new A();
......
A a2 = getAInstance();
......
a1.flag = true;
......
a2.flag = false;随着你的 A 这个类的重新发布,由于 flag 是 private 的,所以张三、李四、王五这些同事都必须修改他们的代码为
a1.setFlag(true);
a2.setFlag(false);
才能通过编译。你的同事会骂你,项目经理也会BS你,项目可能会因此重新测试而使工期延长,你的奖金没准也会因为这个原因被扣掉一部分
封装特性封装就是将客户端不应看到的信息包裹起来。使内部执行对外部来看是一种不透明的、是一个黑箱,客户端不需要内部资源就能达到他的目的。
1.事物的内部实现细节隐藏起来
2.对外提供一致的公共的接口――间接访问隐藏数据
3.可维护性
set
就是单纯赋值。
get
就是单纯取值。
那么就与public数据成员无异,是吗?
public void setFlag(int flag ){
this.flag = flag ;
}
如果单纯这么写,两个是一样的。但在一般的应用中,setFlag可以为赋值加一些判断(就算现在不需要判断,将来可能也需要),而不是直接赋值。
比如
public void setFlag(int flag ){
if(flag>1000)
{
this.flag = 1000 ;
}else
{this.flag=flag
}
}
这样就可以控制flag不超过1000.
比如:
private String name;
protected void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
你觉得这样的代码,和直接将name属性定义成public是一样的么?
而直接访问属性的方式,读与写的权限都是一样的。
如果有100个地方都用到了name
现在要求把name后面加上一个字符串,100个地方要改100遍
如果用set,get方法,直接在方法中加一句就搞定了
我仔细看了下SUN公司的API
set和get方法。
都不是单纯的数据录入与读出。
还是有一定的处理。如:JFileChooser的
public void setAccessory(JComponent newAccessory) {
JComponent oldValue = accessory;
accessory = newAccessory;
firePropertyChange(ACCESSORY_CHANGED_PROPERTY, oldValue, accessory);
}
public class A {
private int width;
private int height;
// with getters & setters for width & height
public int getArea() {
return width * height;
// 如果把area做成字段,你需要分别设置,而且还可能造成面积与长宽不一致
// 甚至可以写更复杂的代码,例如switch-case, 读取数据库
}
}
写属性也有类似功能,具体参考http://topic.csdn.net/u/20091201/15/d5950537-f3a0-4bdd-9718-309517f2c783.html中我的回复
数据成员公有多好。
还要多十来行代码写set和get相当麻烦。
private int age;
public int getAge(){
return age;
}
public void setAge(int value){
if(value <= 0 || age >= 150){
throw new ArgumentException ("chinese wholesalers");
}
this.age = value;
}
}
class A{
private static A _instance;
private A(){
}
public static A getInstance(){
if(_instance == null){
_instance = new A();
}
return _instance;
}
}
private 表示私有的 通过get set方法访问 这样的效果 安全多了不!~
答:42楼,参数是int型的确是有这种好处。但如果只是一种对象类型,你有什么好检查的。
只是单纯的赋值和取值,我觉得本身就没有封装性。(这虽然是一个非常简单的问题,但既然已经谈到这个份上了,我们就把这个问题说透了,以供小虾们参考)
调用有三种方法:[我自己写的,大家请批)1)在本对象中,生成另一个对象的引用,再利用这个引用去调用public方法,再利用此方法获得数据。2)设对方的方法为静态方法,这样直接可以用类名来调用。这也就是说这个方法相当于一个全局方法,当这个方法比较独立和稳定,而又经常被调用到时,这种做法还是可取的。但如果可以使用实例方法的情况下,大量使用这种方式去调用,会造成资源浪费,因为实例方法在执行之后,就会退出内存。即使不被马上回收。3)直接设置对方的数据成员为public,实现数据的直接存取。大部的初级程序员都是这么做的,致使数据成员象全局变量一样,到处都被使用,最后处于环状,五角星状调用,使程序可读性,可维护性大大降低。