在开发我最近的项目时,我发现了一些违反封装和可见性规则的东西,因为我理解它们。
在我的GUI类中,我为我的应用程序中的文本字段和按钮创建了几个类变量,并将它们全部设置为私有。我还为按钮和文本字段设置了getters,返回私有成员的值。在我的SqlStatements
课程中,我引用了getter,然后在getter上调用setText()
方法,它会更改私有成员字段的值。这怎么可能?
例如:
public class InitGUI {
public static JTextField getfNameField() { <---- getter for JTextField
return fName;
}
private static JTextField fName; <---- JTextField variable.
}
public class SqlStatements {
// how is this able to change the value of a private member?
InitGUI.getmNameField().setText("");
}
答案 0 :(得分:11)
您将不可变性与可见性混为一谈。通过为私有字段提供getter(打破封装),您可以将它的方法暴露给外部世界。 (可能是一些改变字段内部状态的方法 - 以及你的类的结果)。
答案 1 :(得分:2)
这怎么能改变私人会员的价值呢?
不更改fName
私有字段的值 - 它仍然是对同一JTextField
的引用。您所做的只是在JTextField
对象上调用方法。
答案 2 :(得分:0)
getter和setter的目的是提供限制/禁用 对私有变量的不必要的修改。
如果这对您没用,则无需将其定义为私有
答案 3 :(得分:0)
你的问题是你对私人工作方式的假设是不正确的,因此,你的代码暴露太多。而不是,
public class InitGUI {
public static JTextField getfNameField() { <---- getter for JTextField
return fName;
}
private static JTextField fName; <---- JTextField variable.
}
public class SqlStatements {
// how is this able to change the value of a private member?
InitGUI.getmNameField().setText("");
}
你最好这样做:
public class InitGUI {
// for heaven's sake, get rid of the statics!
private JTextField fName= new JTextField(10);
public String getfNameText() {
return fName.getText();
}
public void setfNameText(String text) {
fName.setText(text);
}
}
这将限制您的组件仅暴露于您想要的曝光。
同样,请避免不必要地使用静电。
答案 4 :(得分:0)
您对成员在java中的工作方式感到困惑。私人会员确实是私人会员。当您通过getter方法访问该成员时,它确实可以被“修改”。 getter返回存储在成员中的class
实例。无论您对此实例执行什么操作都会影响私有变量,因为它们都是相同的实例。
但它不返回的是该成员存储的memory address
。因此,您无法通过执行来替换实例;
JTextField field = InitGUI.getmNameField();
field = new JTextField(); // this can't affect the original.
这篇文章Is Java "pass-by-reference" or "pass-by-value"?可能有助于按价值性质解释java的引用。
答案 5 :(得分:0)
您可以为JTextField的特定字段提供公共getter,而不是整个对象的getter。这样您就可以避免有人设置字段。
e.g。
public String getFname(){
return fName.getXXXX();
}