为什么在类中声明变量是私有的?

And*_*tin 12 java variables private

伙计我会先道歉,因为我确信这已在其他地方得到解答 - 我找不到能以我理解的方式解释它的答案!我正在做一个MSc转换课程,有一些基本的基础知识,我仍然在努力解决这个问题,包括这个 - 为什么变量私有更好.

假设我有一个名为Person的Java类,带有print方法.我可以创建它并将其定义为:

public class Person
{
    public String name;
    public String telephoneNumber;

    public void print()
    {
       System.out.println(name + " " + telephoneNumber);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在主类中,我可以编写以下代码:

class testPerson
{
  public static void main(String[] args)
  {
    Person test;
    test = new Person();

    test.name = "Mary";
    test.telephoneNumber = "01234 567890";

    test.print();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我这样做,test.print(); 会产生输出:

mary 01234 567890
Run Code Online (Sandbox Code Playgroud)

但是,我知道这被认为是编码不好.变量应该在公共类中是私有的,因为我们不希望人们看到如何存储这些信息或者能够在未经授权的情况下编辑信息.

所以现在,我将编辑Person类以声明两个字符串私有并添加get和set方法,如下所示:

private String name;
private String telephoneNumber;

public void setName (String name)
{
  this.name = name;
}

public void getName()
{
  return name;
}

// same code for telephone methods.
Run Code Online (Sandbox Code Playgroud)

现在,在主类中,我会将设置名称和电话的方法更改为以下内容:

mary.setName("Mary");
mary.settelephoneNumber("01234 567890");
Run Code Online (Sandbox Code Playgroud)

据我正在关注的讲义,这是更有效的(尽管可以更有效地通过做一个人()方法将允许实例化等)

但是,我很难理解为什么这会更好.
在以前的处理方法中,用户可以直接访问变量.但即使通过隐藏变量而无法直接访问它们,用户也可以间接访问和修改它们,从而产生完全相同的结果.

为什么这是首选,毫无疑问,我错过/忽视愚蠢的事情?

Ara*_*ram 30

比萨饼送货类比

  1. 您订购比萨饼送货.
  2. 披萨男孩敲门,希望你付钱.
  3. 你从钱包里拿出钱,交给送货员.(您可以控制隐藏内部细节(驾驶执照等))或者,
    • 你可以将钱包交给送货员,并要求他从中取钱.通过这样做,你不再受控制.您正在公开内部细节.

阅读有关信息隐藏封装不是信息隐藏.


Lou*_*man 14

并不是说它更有效率,而是它更易于维护和良好的实践.

例如,使用setter方法,您可以在实际进行设置之前setTelephoneNumber实际检查String是否是有效的电话号码.如果你把变量公之于众,你就不可能这样做.从一开始就使用setter意味着您可以返回并稍后添加验证,而如果您将变量设置为public,则必须添加setter并修改所有用户以使用setter而不是修改直接变量.


Mar*_*nik 5

人们会给你一百万个反驳的理由为什么它更好,但它只是在某些情况下更好,而不是在所有情况下都明确。例如,以 Java 自己的类为例GridBagConstraints它根本没有方法(如果您不计算clone,它无论如何都有;所有 Java 类都从 继承它Object)。为什么?因为在某些情况下,这实际上更实用。并且GridBagConstraints是最纯粹意义上的 Java Bean:它都是关于属性的,没有业务逻辑。

让我报告实践中的另一个事实:没有 setter 会验证其输入;没有 getter 计算过它的结果。在 JavaBeans 的世界中,任何这样的行为很快就会妨碍setter set 和 getter get的普遍假设。基本上,如果您以任何方式与完全等同的公共领域发生分歧,您就会失败。

现代 Java API,如 Hibernate,通过在与 JavaBean 样式属性平等的基础上接受裸露的公共字段来承认这一事实。早期版本不允许这样做,但是随着 Java 经验的积累,人们终于意识到公共字段是可以的

  • +1 有趣的答案,虽然访问控制是 OOP 最重要的方面之一,但重要的是要意识到它只是一个范式,一个好的想法框架而不是福音。当您看到人们为了“正确的”面向对象而设置的一些字面上疯狂的类继承链时,您会意识到这不是一种完美的方法! (3认同)