美好的一天!
我正在阅读一本关于封装的Java书,它提到了getter和setter方法。
我已经读过要隐藏属性,我必须将我的实例变量标记为“PRIVATE”并制作getter and setter
的“PUBLIC”方法访问数据。所以我尝试制作一个类似但不是传统的代码,如下所示:
public class AddressBookEntry {
private String name;
private String address;
private String telNo;
private String email;
public void getAllInfo() {
name = JOptionPane.showInputDialog("Enter Name: ");
address = JOptionPane.showInputDialog("Enter Address: ");
telNo = JOptionPane.showInputDialog("Enter Tel. No: ");
email = JOptionPane.showInputDialog("Enter Email Address: ");
}
}
我的代码是否暴露了我的变量,因为我直接分配了它?我怎么能做得更好?如果我改为使用传统的getter and setter
方法并在另一个类上分配值,那会更好吗? “隐藏数据”是什么意思?
谢谢。
答案 0 :(得分:7)
您可以使用setter和getter使变量可以从类外部访问。在你的例子中,你将有
public class AddressBookEntry {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
您将从UI类访问name属性(在同一个类中混合UI和业务逻辑并不好):
public class MyPane extends JFrame {
public getAllData() {
String name = JOptionPane.showInputDialog("Enter Name: ");
AddressBookEntry entry = new AddressBookEntry();
entry.setName(name);
// You can't use entry.name = name
}
}
答案 1 :(得分:5)
是和否。封装的关键是它可以防止其他类需要知道你的类在幕后做了什么。如果你将name
存储在String
中(就像你在这里所做的那样),从文件中读取/写入,或者做一些不同的事情,封装点就是你班级的用户这没关系,因为他们看到的所有都是String getName( )
和void setName (String name)
。
由于数据的修改完全在您的类的控制之下,因此它不会破坏封装。如果您 将name
存储到文件中,那么您可以在getAllInfo
中执行此操作,而不会让该类的任何其他用户更明智。由于类的外部的可观察行为仍然隐藏了类的内部所做的事情,因此它仍然被封装。
那就是说,这是一种非常规的方法。就像我在第一段中描述的那样,使用访问器方法(getter和setter)是一种更惯用的方法,对于使用您的代码的其他人来说更容易理解。你可以做你做的事情,它不会破坏封装,但它不是我称之为优雅或典型的。
答案 2 :(得分:3)
私有类成员(属性,字段)的想法是仅在声明类(而不是实例!)中直接访问它们。所有其他类都必须使用其他访问器,例如getter和setter方法。因此,{em>如何 AdressBookEntry
存储名称,地址,telNo和电子邮件值的方式完全隐藏在课堂内。
你没有有来使用getter或setter,尽管有时也有很好的理由在课堂上这样做。如果在设置值之前进行一些记录或验证,则使用getter和setter有时会有意义。
答案 3 :(得分:1)
这不违反封装,因为它不会将内部数据暴露给另一个类。您可能希望查看Model-View-Controller(MVC),以帮助将您的界面与数据分开。
传统的你根据需要为每个变量创建一个getter和setter,如下所示:
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
不要为不需要在类外部访问的变量创建getter,也不要为不需要在类外部设置的变量创建setter。
如果遵循MVC并使用上面的传统getter和setter,你可以在其他地方使用视图代码并调用类似
的内容myAddressBookEntry.setName(JOptionPane.showInputDialog("Enter Name: "));
答案 4 :(得分:1)
我同意所提供的所有重要答案。我想增加使用封装的另一个好处,就是通过从客户端隐藏数据(就像上面描述的例子一样),你可以保证如何设置和获取这些实例变量您的类更易于维护和测试(即,如果您有许多客户端操作您的对象变量,您不需要逐个类地编写新功能,而只需修改getter和setter)。
通过仅使用对象setter和getter,可以从外部世界隐藏其实现的细节。这是一个很好的优势,因此尝试与您的类交互的其他对象将无法破坏其功能。这也增加了系统有效实施的可能性。
答案 5 :(得分:1)
我发现上面的答案已经回答了你的问题。但是,我发现您的代码存在另一个问题,即安全性和数据完整性问题。您将直接从用户的输入中填写您的类成员,无需对其进行任何验证。例如,您可能想要检查电子邮件地址是否具有xyz@abc.com模式。恶意用户也可能在输入中提供非常长的字符串,从而导致意外错误。