面向对象编程 - 字段 vs 方法

4

这个问题不是针对Java的,但是示例代码是Java代码。

有时候你会遇到非常简单的对象,比如以下代码:

public class Coordinates {
    private int x;
    private int y;

    public Coordinates (int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void setX (int x) { this.x = x; }
    public void setY (int y) { this.y = y; }
    public int  getX ()        { return x; }
    public int  getY ()        { return y; }
}

我认为直接访问字段比通过方法更加高效。而且,代码看起来会更简单。使用也会更简单,类定义不会包含4个没有实际作用的方法(即不必要的样板代码)。某种程度上,我想到了C语言中的struct或Pascal中的record的用法。
我的做法可能是这样的:
public class Coordinates {
    public int x;
    public int y;

    public Coordinates (int x, int y) {
        this.x = x;
        this.y = y;
    }
}

那么为什么第一种方式似乎更受欢迎呢?感觉是在强制将某些内容变成一个对象。它只是将值捆绑到一个变量中,为什么要仅仅为了使用OOP而使用呢?当然,我保留了构造函数。当值最初被赋值时,它非常方便,但实际上除了可能会设置两个字段的方法(如构造函数)之外,没有其他必要的方法。
我知道OOP对许多事情很方便,但对我来说,这似乎不是其中之一。我这样想错了吗?

2
长话短说:由于事情会变化,当需要添加行为/验证时,您将需要创建setter和getter。如果此时有30个其他应用程序正在使用您的库并直接调用您的公共字段,那么祝你好运重构所有这些应用程序。 - dcastro
1
@dcastro所说的是我一直使用getter和setter的原因。但是当你考虑它时,你很可能会编写一个最终应用程序,其他应用程序不依赖于它。我的大部分编码都是针对游戏开发的,每个对象上有公共x、y、spd等属性非常清晰易懂,也更容易处理。 - Coderino Javarino
2
到目前为止,加1分。但是还有一点需要记住,在Java中,setter和getter通常是内联的。因此,它们没有性能成本,因为它们变成了直接公开字段的等效方式,但没有维护的权衡。 - Chris K
1
话虽如此 - 有些情况下你知道你不需要getter/setter。@Heimdall提供的例子实际上是一个很好的例子。经典的例子是类Point,它有xy字段。根据定义,点可以有任何xy坐标,因此未来非常不可能需要添加验证。 - dcastro
1
灵活性和可维护性: 如果今天您认为您不需要对数据进行验证或处理,良好的面向对象设计确保您为未来做好规划。 - Sagar Pudi
显示剩余4条评论
2个回答

0

没有人强迫程序员定义4个getter/setter。如果你愿意,你可以将这两个字段设为public,并且不定义任何getter/setter。

但是你必须确保未来的原始想法保持不变,即永远不会需要非平凡的getter/setter。如果是这种情况,你可以直接访问这些字段,并将它们设为public


0

我能够想到几个原因:

(1) 约定 - 当我使用一个不熟悉的库中的对象时,当我执行 .get 时,我的 IDE 会提供一个属性列表。如果我在一个不太熟悉的库中工作,这可能是一个优势。

(2) 序列化 - 许多库(例如 Jackson 框架)使用 bean 作为标准。然后,框架通过查看以 get 或 set 开头的方法来确定对象具有哪些属性。显然,这不是一个硬性约束,但它很方便。

(3) 并发性 - 直接公开属性依赖于客户端使对象线程安全。如果我有 getter 和 setter,则可以确保它们使用适当的同步。因此,我可以保证对象的线程安全性。显然,最好让对象实现自己的线程安全性,而不是依赖客户端。当我首次编写对象时,我可能事先不知道是否应该实现线程安全性。

(4) 可维护性 - 你可能希望在将来某个时候向你的 getter 或 setter 添加额外的逻辑。


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