3

昨天我正在编写自己的 LinkedList 实现。我正在做这样的事情:

public class Node
{
    Node next;
    int value;

    public Node()
    {
       next = null
       value = 0;
    }
}

然后在使用时Node我正在做node.nextnode.value. 然后我意识到——等等,我到底在做什么?这些实例变量应该是private,然后我应该使用 getters() 和 setters() 访问,比如getNext()and setValue()

这让我想知道,除了实例变量之外,什么时候需要private

4

4 回答 4

4

从技术上讲,您要问两个问题:标题问题“何时适合拥有公共实例字段”和最后一句“何时适合拥有非私有实例字段”。

什么时候有公共实例字段合适?几乎每个人都知道答案几乎是永远不会。我认为它们有时适用于非常小的值类,它们的行为类似于简单的 C 结构。一个很好的例子是 java.awt.Point 和 java.awt.Dimension。

这些实际上是特别好的例子,因为尽管它们很简单,但它们最终演变为使用访问器方法,这是一个很好的教训:即使是一个看起来如此简单以至于公共字段似乎可以接受的类也有可能成为需要封装的东西. (Point 和 Dimension 继续保留这些公共字段以实现向后兼容性。)

什么时候适合使用非私有实例字段?大多数人没有利用没有访问修饰符的字段和方法(和类)是包私有的这一事实,但是包私有字段在很多情况下都很有用。由于它们只能由同一个包访问,因此通常情况下它是您的代码,您可以相信自己不会做会破坏您的对象的“坏事”。我想说包私有字段的合法用途比公共字段要多得多。

也就是说,点/维度规则仍然适用:有很多次我认为我可以摆脱包私有字段,但后来才意识到我需要通过 get 和 set 方法进行封装。

受保护的字段的使用可能远远超出应有的范围。在我看来,让子类直接修改状态而不是通过方法很少有很大的收获。

于 2013-11-07T01:09:34.440 回答
1

经典的例子是一个表示二维数学点的类。

public class Point {
    public float x;
    public float y;

    public Point( float x, float y ) {
        x = x;
        y = y;
    }

    public void scale( float c ) {
        x *= c;
        y *= c;
    }

    public void rotate( float angle, Point center ) {
       // whatever this logic is; I forget
    }   
}

APoint实际上只是一个容器,可以容纳两个可以任意变化的浮点数。通过允许访问xy直接访问,而不是强迫用户通过 getter 和 setter,你不会真正伤害任何东西。同时,像缩放和旋转这样的一些操作很常见,因此值得创建一个类来提供对坐标进行必要数学运算的方法。


请原谅(或者更好的是,更正)代码中的任何语法或其他错误。我已经很久没有写过Java了。

于 2013-11-07T01:03:26.710 回答
1

当您实际上不需要保护它们免受任意访问或更改时(例如,当值被允许采用任何整数时,或者“检索的值”到“对象中的值”的简单空映射时),这没有什么意义在它周围包裹一个 getter 或 setter。

如果是这种情况,代码有时看起来更自然,使用:

object.value = 42;

而不是:

object.setValue (42);

(尽管对来说差异很小)。

话虽如此,我仍然更喜欢 getter 和 setter,因为如果将来某个时候需要将逻辑合并到成员中,将公共成员更改为该成员的 getter/setter 将破坏该类的 API,涉及更改给所有使用它的客户。

这可以包括(但绝不限于):

  • 限制您可以将成员设置为的值。例如,将物体的年龄限制在 0 到 137 亿年之间 :-)
  • 导出要提取的值,例如从摄氏度成员计算华氏温度。
  • 对设置值有副作用,例如更改文件名涉及将某些文件预加载到缓存中。
于 2013-11-07T01:00:40.170 回答
0

您必须查看 Java 中的访问说明符。快速参考:http ://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

于 2013-11-07T00:59:19.287 回答