面向对象编程中的访问修饰符

时间:2010-03-11 20:17:25

标签: java c++ oop programming-languages computer-science

我不了解OOP中的访问修饰符。为什么我们在Java实例变量私有中使用,然后使用公共getter和setter方法来访问它们?我的意思是这背后的推理/逻辑是什么?

你仍然可以使用实例变量,但为什么在公开变量时使用setter和getter方法呢?

请原谅我的无知,因为我只是想了解原因?

提前谢谢你。 ; - )

9 个答案:

答案 0 :(得分:11)

这称为数据或information hiding

基本上,你不希望用户(阅读:其他程序员或你自己)在你班级的内部进行攻击,因为这样就很难改变。

另一方面,界面和实现之间的清晰分离(理论上)使得在内部更改内容变得容易,而不会影响您班级的任何用户。

例如,假设我有Button字段的public String text控件。现在每个人都开始使用我的Button,但我意识到只要文本发生变化,按钮就应该在屏幕上重新绘制。我运气不好,因为我的对象在分配text时无法检测到。如果我做了private并提供了setText(),我可以添加对该setter方法的重新调用。

作为另一个例子,假设我有一些类在其构造函数中打开文件并将其分配给public FileStream file。如果无法打开文件,构造函数将引发异常。因此,类中的其他方法可以假定该字段始终有效。但是,如果有人在我的课堂上闲逛并将file设置为null,我班上的所有方法都会突然崩溃。

答案 1 :(得分:6)

一个经常被忽视的非常重要的一点:你不拥有为每个领域提供一个getter和setter!实际上,大多数字段都不应该只有一个getter(实际上只有getter)。

拥有除私有属性和公共getter以及setter之外的其他类的设计与使用公共字段一样糟糕。这是一种名为anemic domain model的反模式。关键是getter和setter允许你在简单的数据保存之外向模型添加行为和逻辑 - 在许多情况下,这意味着没有getter或setter(或两者)。

答案 2 :(得分:1)

不同之处在于,使用getter和setter可以控制实例字段的访问方式。您可以提供防御性副本,不可变视图,甚至是实例字段的转换。您已隐藏其他人的真实实施细节。 这是件好事!

你越是隐藏,同时仍然使你的界面友好和有用,越好。其他人不需要知道事情是如何运作的(因为他们可能会想做他们不应该做的事情);他们只需要知道事情会以某种方式发挥作用。

答案 3 :(得分:1)

另一点是encapsulation - 如果您选择更改此变量的处理方式,例如要始终返回/存储副本,您可以在一个地方(getter / setter)执行此操作而不会破坏任何内容。

答案 4 :(得分:1)

如果您的类是不可变的,那么将变量公开为公共变量没有任何错误。 (都将是公共决赛) 并且没有规则getter应该总是返回变量。 或者setter应该将变量设置为.. 您可以围绕私有变量的访问包含大量规则/修饰符等 (数据封装)

答案 5 :(得分:1)

首先,并非所有数据成员都应该拥有getter和setter,我想你可以看到保持这些变量私有的优点。

第二,大多数课程不仅仅是随机的数据集合。它们代表了你应该能够独立推理的事情。通常,这意味着它们具有开发人员可以依赖的某些属性(通常称为“类不变量”)。例如,Rectangle类应该具有以下属性:在角点之间绘制线条会产生彼此成直角的线条。如果这些点是公共数据成员,那么任何随机应用程序都可以更改一个点,然后你就会得到一个不是矩形的矩形。如果你有一个setter函数,你可以正确处理它。

第三,考虑维护。在某些时候,您可能想要修改类实现,您可能想知道有多少事情需要改变。如果数据成员是公共的,则更改实现的任何细节都可能会破坏使用该类的任何程序。你被困住了。如果有getter和setter,你可以补偿它,所以设置一个值可以在内部做一些或多或少复杂的事情,以获得与以前相同的效果。如果你有更抽象的成员函数,那么你做出改变的问题就很少了。

答案 6 :(得分:0)

您将类成员变量设为私有,以控制您可能无法控制的其他代码可以访问和操作它们的方式。

如果您只是在编写玩具代码,那么看到这一点可能会很棘手,但是当您编写其他人将使用和依赖的代码时,您就会明白。

作为一个简单的例子,说一个类成员变量永远不会设置为null很重要 - 比如它会破坏你的类。如果你将该字段设为public,那么任何其他代码都可以将该变量设置为null,你无能为力。

如果将其设为私有并改为提供setter方法,则可以保护成员不被设置为null,是否可以控制是否抛出已检查/未检查的异常,或者是否忽略该尝试。

答案 7 :(得分:0)

这些是使用OOP,多态,继承和封装的主要优势。

封装允许您使用私有访问修饰符隐藏对象的实现或数据。

另一方面,您希望改变数据,从而创建setter方法。 希望这会有所帮助。

答案 8 :(得分:0)

您正在谈论OOP基础知识。这个主题值得读一本好书。不同的博客和论坛(其中一个是SO)不适合获取基础知识。

如果您真的想深入了解对优秀开发人员至关重要的基础知识,请阅读相关书籍。 “代码完成”或“面向对象的分析”值得阅读。