0

在开发我最近的项目时,我发现了一些违反我理解的封装和可见性规则的东西。

在我的 GUI 类中,我为我的应用程序中的文本字段和按钮创建了几个类变量,并将它们全部设置为私有。我还为返回私有成员值的按钮和文本字段设置了 getter。在我的SqlStatements课堂上,我参考了吸气剂,然后打电话setText()getter 上调用方法,它会更改私有成员字段的值。这怎么可能?

例如:

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("");
}
4

6 回答 6

11

您将不变性与可见性混淆了。通过为私有字段提供 getter(您打破封装),您将其方法暴露给外部世界。(可能是一些改变字段内部状态的方法 - 结果是你的类)。

于 2013-07-22T11:09:39.973 回答
2

这如何能够改变私人成员的价值?

不会改变fName私有字段的值——它仍然是对相同的引用JTextField。您所做的只是调用该JTextField对象的方法。

于 2013-07-22T11:10:01.747 回答
0

getter 和 setter 的目的是限制/禁用对私有变量的不需要的修改。

如果这对您没有用,则无需将它们定义为 Private

于 2013-07-22T11:10:15.093 回答
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);
    }

}

这会将您的组件的曝光限制在您想要的曝光范围内。

再次,请避免不必要地使用静态。

于 2013-07-22T11:24:14.063 回答
0

您对成员在 java 中的工作方式感到困惑。私有成员一开始确实是私有的。当您通过 getter 方法授予对该成员的访问权限时,它确实可以“修改”。classgetter 返回存储在成员中的实例。无论你对这个实例做什么都会影响私有变量,因为它们都是同一个实例

然而,它不返回的是memory address该成员存储的那个。因此,您不能通过这样做来替换实例;

JTextField field = InitGUI.getmNameField();
field = new JTextField(); // this can't affect the original.

这篇文章Java 是“按引用传递”还是“按值传递”?可能有助于按价值性质解释 java 的引用。

于 2013-07-22T11:24:37.933 回答
0

您可以为 JTextField 的特定字段提供公共 getter,而不是整个对象的 getter。这样您就可以避免有人设置字段。

例如

public String getFname(){
return fName.getXXXX();
}
于 2013-07-22T11:24:45.850 回答