要真正理解封装的含义,必须通过类公共方法访问类私有字段的示例是按照定义的,但实际上它并没有什么区别,因为该字段仍然可以按原样访问。
所以,我认为在 getter/setter 内部应该有一些处理来隐藏字段的处理方式。但它打破了背后pojos的原则。如何处理这种情况?
7 回答
我不确定您所说的“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;
}
}
封装意味着不暴露你的类的内部。
在 Java 上下文中,这意味着您的类的属性不应被其他类访问,而是您的类应提供允许访问属性的方法。在 POJO 类的情况下,这些方法只允许设置(setters)和获取(getters)来自 POJO 类的属性值。
封装的目的是保护你的类的属性不被其他类修改。您的班级显然可以使用班级中的属性做任何您想做的事情。
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 岁。
它仍然可以访问,但您会看到当您直接使用它(公共变量)时,您可以不受任何限制地更改变量的值。将这种私有变量与 setter 和 getter 方法一起使用的好处是,您可以在 setter 方法中编写代码来检查值集是否在预期范围内。或者您甚至可以以不同于表观视图的形式存储该值。例如,您可以通过将偏移量添加到 setter 方法的参数值来存储变量的值,而在 getter 方法中,您可以只恢复过程(封装)。当值集不在预期范围内时,您甚至可能抛出异常。
Example1:这里 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;
}
这就是封装的使用......一切顺利
不,该字段无法按原样访问。使方法成为 getter 或 setter 所需的一切都是正确的签名。
public String getFoo() {
return null;
}
这是 a 的完美吸气剂String foo
,即使它返回null
。
public void setFoo(String foo) {
// do nothing
}
这是同一个成员的完美二传手,即使它什么也不做。
不知道为什么人们通常将数据封装与数据隐藏混为一谈。数据封装只是意味着将数据组合在一起,而数据隐藏是一种存储这些数据的方式,因此其他人无法知道它的内部实现。
假设您有一个 PersonalInfo 类,其中有姓名、性别、年龄等字段。作为程序员(您是),您将为用户提供一些输入这些字段的方法,使用 setter methods.IF 将它们保存在您的 PersonalInfo 对象中用户希望看到您简单调用 getter 的信息并显示信息。您的实现可能会将此变量存储在地图中可能会有所不同。所以你可以说
public void setName(String name){
SomeMap.add("name",name);
}
注意 *你是程序员,你总是知道*n 的实现。保持字段私有是只允许您的类方法访问您的数据。
想象一下这样。用户可以创建一个对象。他可以使用 getter 和 setter 设置所有字段。使用 DOB(出生日期)计算年龄可能是您的实现,在这种情况下,您将不提供年龄设置器。在这种情况下,用户不能说 myObj.age=23。这纯粹是你的实现。希望这能消除混乱!
封装就是限制对类变量的访问,规范编辑它们的方式。
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 类是由同一个人编写的,则不会有任何混淆。但实际上情况并非如此。