如果类只有getter和setter,为什么Java中的实例变量应该是私有的
我在一次采访中被问到以下问题,我很想知道答案 有以下两类:如果类只有getter和setter,为什么Java中的实例变量应该是私有的,java,oop,Java,Oop,我在一次采访中被问到以下问题,我很想知道答案 有以下两类: public class EmployeeA{ public int empId; } public class EmployeeB{ private int empId; public void setEmpId(int empId){this.empId = empId;} public int getEmpId(){return empId;} } 有两个类,其中一个类有一个公共实例字段,另一个
public class EmployeeA{
public int empId;
}
public class EmployeeB{
private int empId;
public void setEmpId(int empId){this.empId = empId;}
public int getEmpId(){return empId;}
}
有两个类,其中一个类有一个公共实例字段,另一个类有一个带有getter和setter的私有字段。在这种情况下,哪种实施方式更好?为什么?
[我已经了解到,将实例变量设为私有是更好的主意。但在这两种情况下,我都可以修改empId属性的值。]他们可能要寻找的一个词是
通过封装私有字段值,您有机会更改将来如何设置/检索该值的逻辑。例如,您希望在集合上验证,在获取时过滤。通过封装该值,您可以创建一个API,该API允许更好地进行维护。访问器getter和mutator setter是JavaBean的要求,但并非Java中的所有类都必须遵循此设计模式。为什么不创建一个采用id的构造函数,或者更好的是一个静态工厂,将这个类创建为不可变的呢。然后,您可以为id提供访问器。通常情况下,无法更改对象的id不是一个好主意,如果id在地图中用作键,并且您更改了它,那么祝您好运检索到您的对象。。。使类不可变可以解决此类问题 可能有点离题了,尽管人们在谈论getter/setter时通常会谈论封装,但getter/setter实际上离正确的封装还很远 这本名著值得一读。当我们说getter和setter是邪恶的时,并不意味着我们应该直接公开变量。它是通过在类中提供有意义的行为来进一步隐藏内部数据,而不是为属性提供访问器。尽管有很多情况下我们仍然需要访问器,但在设计时这是值得注意的
回到您的问题,如果是我,我将回答:提供getter和setter提供了最低级别的封装,并允许我们在设置和获取属性时做额外的工作或派生数据。但是,为了进行适当的封装,我宁愿设计Employee类来提供适当的行为,不要简单地充当一个只提供一堆getter/setter的值对象。保持属性私有并根据需要提供getter和setter方法有助于更好的封装和更少的耦合。用外行的话说,OOP开发人员应该是一个控制狂,他总是尽可能地控制自己的东西,这正是我在采访中所说的。但他引入了一个约束,“在get/set操作期间不需要任何更改”。所以我很好奇,除了getter和setter中的封装或修改之外,这背后是否还有其他概念。好吧,像所有其他OOP概念一样,多态性、继承性等,它们都是交错的。一种情况是,您现在构建的类将被继承。再次强调,创建一个公共方法getter/setter/或任何其他方法都是objects API,您的说法是子类将符合您的API。因此,这个类可以设置一个局部变量,一个子类可以为这个子类多态性做一些更重要的事情。许多框架JPA、JAX-B等都依赖于getter/setter方法来识别POJO属性。最后,对于多注释,很抱歉,注释长度有限。另一个选项可能是,它使您的字段值可用于反射,特别是在使用SecurityManager并且私有字段实际上受到保护时=。如果您的代码或您正在使用的代码正在使用反射,那么利用POJO框架和/或使用getter/setter方法签名通常比正确获取策略文件更容易=