使用getter和setter(只获取和设置)而不是简单地为这些变量使用公共字段有什么好处?

如果getter和setter所做的不仅仅是简单的get/set,我可以很快地解决这个问题,但我不是100%清楚如何做到:

public String foo;

比:

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }

而前者需要的样板代码要少得多。


当前回答

如果您不需要任何验证,甚至不需要维护状态,即一个属性依赖于另一个属性,那么当一个属性发生更改时,我们需要维护状态。您可以通过公开字段而不使用getter和setter来保持简单。

我认为OOP会随着程序的增长而使事情变得复杂,这对于开发人员来说是一场噩梦。

一个简单的例子;我们从xml生成c++头。标头包含不需要任何验证的简单字段。但仍然像OOPS访问器一样,我们生成它们的方式如下。

const Filed& getfield() const
Field& getField() 
void setfield(const Field& field){...} 

这是非常冗长的并且不是必需的。一个简单的

struct 
{
   Field field;
};

足够且可读。函数式编程没有数据隐藏的概念,它们甚至不需要它,因为它们不会改变数据。

其他回答

原因有很多。我最喜欢的是当你需要改变行为或调整你可以设置的变量时。例如,假设您有一个setSpeed(intspeed)方法。但你希望你只能将最大速度设置为100。您可以执行以下操作:

public void setSpeed(int speed) {
  if ( speed > 100 ) {
    this.speed = 100;
  } else {
    this.speed = speed;
  }
}

现在,如果代码中的每个地方都使用公共字段,然后意识到需要上述要求,该怎么办?寻找公共领域的每一种用法,而不仅仅是修改你的setter。

我的2美分:)

getter/setter的一个相对现代的优点是,它使在标记(索引)代码编辑器中浏览代码变得更容易。例如,如果您想查看谁设置了成员,可以打开setter的调用层次结构。

另一方面,如果成员是公共的,则这些工具无法过滤对该成员的读/写访问。因此,您必须费力地使用该成员。

OO设计的基本原则之一:封装!

它给您带来了许多好处,其中之一是您可以在幕后更改getter/setter的实现,但只要数据类型保持不变,任何具有该值的使用者都将继续工作。

考虑使用访问器是有充分理由的,因为没有属性继承。请参见下一个示例:

public class TestPropertyOverride {
    public static class A {
        public int i = 0;

        public void add() {
            i++;
        }

        public int getI() {
            return i;
        }
    }

    public static class B extends A {
        public int i = 2;

        @Override
        public void add() {
            i = i + 2;
        }

        @Override
        public int getI() {
            return i;
        }
    }

    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.i);
        a.add();
        System.out.println(a.i);
        System.out.println(a.getI());
    }
}

输出:

0
0
4

访问器和赋值器的一个优点是可以执行验证。

例如,如果foo是公共的,我可以很容易地将其设置为null,然后其他人可以尝试调用对象上的方法。但它已经不在了!使用setFoo方法,我可以确保foo从未设置为null。

访问器和赋值器也允许封装-如果你不应该在值设置后看到它(也许它在构造函数中设置,然后被方法使用,但不应该被更改),那么任何人都不会看到它。但如果您允许其他类查看或更改它,则可以提供适当的访问器和/或赋值器。