【问题标题】:public and private access modifiers公共和私有访问修饰符
【发布时间】:2011-01-31 02:51:04
【问题描述】:

如果我们可以通过 setter 和 getter 访问私有成员,那么 private 有什么用?

【问题讨论】:

  • @Frank 并不重要...

标签: access-modifiers


【解决方案1】:

您需要私有来强制执行封装。将某些东西的实现与接口分开是面向对象编程的基本范式之一。这减少了不同程序部分之间的耦合,并且从长远来看使其更易于维护。

举个例子:

class toto {
  private String someThing;

  public String getSomething();
  public void setSomething(String Something);
}

如果您将上面的内容更改为简单地将 someThing 公开,那么您的代码肯定会减少,但如果有一天 someThing 需要更改为更复杂的对象以实现某些新功能,而旧代码仍然可以与字符串一起正常工作,那么您需要改变一切。通过隔离 someThing 的内部表示,您可以更轻松地改进系统

class toto {
  private ComplexSomeThing someThing;

  public String getSomething(){ someThing.toString();}
  public void setSomething(String something){ something = new ComplexSomeThing(something);}
  public ComplexSomeThing (getComplexSomething();
  public void setComplexSomething(ComplexSomething someThing);
}

还有其他原因使封装成为一件好事(tm),这只是说明这一点的一个愚蠢的例子。


编辑 关于使用受保护与私有或使用类似于某些语言(Delphi、C#)中的属性而不是 getter 和 setter(如在 Java 中)的概念,现在存在一些争论。 受保护而不是私有将允许客户更轻松地更改代码,但它确实会更多地暴露系统的内部结构,因此需要在 API 的可用性和可维护性之间寻求平衡。然而,封装的基本原理仍然存在。 无论选择何种选项,仍然需要公开一致且处于同一抽象级别的功能,并隐藏如何完成的血腥细节。

对我来说,争论不是要宣布对私有的圣战,而是要找到一种方法来提供可扩展性和灵活性,同时又不破坏 API 的连贯性。

Heresomeinteresting 如果您想进一步挖掘,请阅读有关私人的信息。但是我必须强调,在形成关于私有的观点之前,你应该真正掌握encapsulationpolymorphism 的概念,它们表面上的简单确实隐藏了一些微妙的complexities

【讨论】:

    【解决方案2】:

    因为 getter 和 setter 可以充当代理。他们这样做是为了让您可以隐藏类的实际内部,只让外部类通过方法访问数据。允许您随意对待班级的内部人员。

    仅仅因为你的 getter/setter 被命名为 getName() 而你的属性被命名为 name,并不意味着它总是这样。

    如果您想将变量更改为fullName。如果您直接访问公共变量,则更改会破坏很多代码。相反,您可以简单地重新映射getName() 从中检索数据的位置。

    我最好的例子之一是我自己的 URL 类,我允许在其中创建和操作 URL。如果要设置方案,可以获取$obj->setScheme()。但是,您不知道我是否在每次更改 URL 时手动创建字符串,是否将它们存储为单独的部分。这给了我灵活性,因为我可以随意存储您的数据。

    此外,我可以在存储数据之前对其进行操作。在我的 URL 类中,我假设所有方案和主机名都是小写的。我可以通过将通过setHost() 保存的所有字符串转换为小写,然后存储它们来标准化这一点。如果我使用公共变量,您将不得不假设放入数据的客户端正确地存储了它。

    他们还可以验证传入的信息,以确保它是有效数据,如果不是,则会导致错误。

    【讨论】:

      【解决方案3】:

      没有人强迫你为每个变量都输入 getter 和 setter。实际上,对每个变量盲目地使用私有成员 + 虚拟 getter 和 setter 是没有意义的,尽管许多“面向对象封装”教程出于某种原因一直这样做。一方面,这种封装从并发的角度来看是no封装。

      【讨论】:

        【解决方案4】:

        我认为您真正想了解的是为什么我们使用带有私有支持字段的公共属性,而不仅仅是使用公共字段。像这样的SO有几个问题;这是一个:

        What is the difference between a Field and a Property in C#?

        【讨论】:

          【解决方案5】:

          到目前为止,我认为您有很好的答案(信息隐藏等等)。只是想添加一个关于使用 setter 的建议。

          正如您提到的,使用访问器会使私有变量变得毫无意义,并且在某些环境中,使用 getter 和 setter 的性能后果只会使其变得毫无价值。

          另一方面,如果您没有这样的顾虑,我认为使用 getter 并没有那么糟糕,但是在使用 setter 之前您应该三思而后行。它们使您的对象可变,这在并发环境中尤其难以维护。

          【讨论】:

            猜你喜欢
            • 2017-01-03
            • 2019-07-15
            • 2016-11-22
            • 2017-11-11
            • 2017-12-22
            • 2015-11-26
            • 2015-09-26
            • 2014-08-27
            相关资源
            最近更新 更多