访问修饰符的目的是什么?

11

我知道这适用于许多语言,不仅仅是Java,但那是我最熟悉的语言。

我了解修饰符的作用以及如何使用它们。我只是想知道,为什么我们需要它们?为什么不能让每个对象都可以访问,无论它是否需要被访问?


6
这被称为封装。 - Mitch Wheat
6个回答

21

当你需要维护一个更大的项目时,API的访问权限就更加重要了。当一个方法或变量是公共的时,你必须小心修改它,因为你永远不知道代码库中哪些部分依赖于它的确切行为。

但是当一个变量或方法是私有的时,你就知道它不会在类外部被使用。这意味着当你进行修改时,你只需要关注更少的代码内容。

通过将类成员设置为私有和公共,你可以清晰地将外部接口与内部实现分离。外部暴露的内容越少,你对内部实现的自由度就越大。

例如,当你总是将变量设置为私有,并通过getter和setter方法访问它们时,你可以将其从变量改为计算值,然后甚至为了性能原因添加缓存。如果它是一个公共变量,你就必须在使用该变量的所有代码处进行修改。但是,如果你通过getter和setter方法将其暴露给外界,所有其他代码都可以像没有任何变化一样继续使用该类。


2
能够对实现进行更改只是答案的一部分。 - herman
2
“外部世界”的用法是误导性的。如果我办公室外面的一棵树是否能够访问我的类里面的变量,我为什么会感到担心呢?他们应该说“对于你的项目中的所有其他代码”之类的话。 - lxknvlk

1

访问修饰符用于设置类、变量、方法和构造函数的访问级别。这为个人提供了更好地控制应用程序隐私的机会。有4种访问修饰符。

修饰符 | 类 | 包 | 子类 | 全局

无修饰符:--|----是----|------是--------|--------否--------|-----否----|


私有的:-------|----是----|-------否--------|--------否--------|-----否----|


公共的:--------|----是的----|------是的--------|-------是的-------|----是的----|


protected:---|----是----|------是--------|-------是-------|-----否-----|


关于您的问题,我们确实需要和使用访问修饰符,因为我们需要限制谁可以调用我们的程序以及以何种方式调用。
此外,当涉及到变量时,如果您将某些内容公开,那意味着我可以直接访问它。因此,我可以不遵循您通过方法提供的指导而随意操作。
例如:
public int maxUsers;


public void setMaxUsers(int users) throws IllegalArgumentException{
   if(users > 0 && users <= 1000){
      maxUsers = users;
   }else{
      throw new IllegalArgumentException("The users can not be less than 0 or greater than 1000")"
   }
}

想象一下,你的整个程序都基于它的maxUsers变量。既然你让我直接访问这个变量,我可以这样做:maxUsers = -15;而不使用setMaxUsers方法,这将使你的程序表现异常(在最好的情况下)。

1
抱歉打扰一个老帖子,但我想提一下你在开头包含的那张图表,其中列出了4个访问修饰符及其范围,对我非常有帮助。点个赞,这样它就能更加引人注目了。 - Ashwin Gupta

1
更多或少的,它们被用于控制谁可以访问您的成员变量和函数。这是 Java 中封装的广义概念起作用(http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming))。
来自 Oracle 文档:
访问级别修饰符确定其他类是否可以使用特定字段或调用特定方法。有两个访问控制级别:
在顶层 - public 或 package-private(没有显式修饰符)。
在成员级别 - public、private、protected 或 package-private(没有显式修饰符)。

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

为什么你应该这样做:

这与使用意图有关。最好的描述可能是一种设计选择,可以通过代码库来引导使用。通过标记某些内容为私有,您告诉其他开发人员,此字段或方法不应在其当前目的之外使用。在大型项目中,随着时间的推移,它变得非常重要。它有助于传达类的目的和预期用途。


1
我理解它们的作用,我只想知道为什么不能所有对象都是公共的? - sparklyllama
1
@sparklyllama 因为有些字段你不想让其他人访问。比如说,如果有人在使用你的程序,你不希望他们搞砸任何东西,所以你会将这些字段保护起来并设置为私有,从而禁止任何更改。 - aafonso1991
1
这与使用意图有关。最好的描述可能是一种设计选择,可以通过代码库中的使用来指导。通过标记某些内容为private,您正在告诉其他开发人员不应该使用该字段或方法。这在长期更换开发人员的大型项目中变得非常重要。 - Durandal

1
使字段和方法私有化可以防止其他类不当地依赖于类的具体工作方式。公共接口(最好情况下是实际接口)描述了基于正在进行的工作的语义客户端代码应该如何与库交互。然后,实现者可以自由地使用任何适当的技术来实现该接口,并且可以进行重大的幕后更改,因为客户端代码将继续工作。
每天的例子是Collections接口组。大多数时候,逻辑上不重要的是代码知道正在使用什么特定类型的Set,只需知道它是支持某些操作并且没有重复项的集合即可。这意味着接受Set的方法将与任何Set一起使用,包括HashSet和ImmutableSet,因为编写接口的人没有在实现的内部进行探测。
一个例子是,一些程序员倾向于在使用密码学时使用com.sun命名空间中的包,这会导致问题。升级到新版本的JRE通常会破坏此代码,如果程序员使用正确的javax.crypto接口和工厂方法而不是在JVM内部探索,则代码将正常工作。

1
为了避免其他类直接访问类的内部成员。
这对于避免成员变量以不受控制的方式改变(例如,没有适当的验证,没有通知监听器等)非常有用。
另一个避免这种情况的原因是,内部实现可能随时更改,但您不想破坏使用它的代码。
正如其他人所指出的那样,这个概念被称为封装。

0

解释

私有成员只能在声明它的类中访问。 没有访问修饰符的成员只能在同一包中的类中访问。

或者

如果一个变量在类内被设置为protected,那么它只能通过继承在同一类或不同包中的子类中访问。

受保护的成员可以在同一包中的所有类以及其他包中的子类中访问。

公共成员可被所有类访问(除非它位于不导出所声明包的模块中 这是一个更好的表格版本。(具备模块列,未来兼容)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接