我试图了解将类变量设为私有而非公共的好处。我理解getters / setters可以访问/修改私有/受保护的数据,但它的唯一目的是“阻止我破坏我的数据”?示例:我不知道怎么说
$person->age = x;//bad?
具有不同于
的潜在可能性$person->set_x(x);//reccommended in OOP articles
答案 0 :(得分:13)
一切都与封装有关。
假设您使用$person->age = x
。现在,它会工作正常,让我们说你在100个地方都有这条线。后来发现你想要将age
限制为大于0的数字。通过直接访问成员变量,就无法轻易地强制执行该限制。
但是,假设你最初在这100个地方写了$person->set_age(x)
。现在,您可以从
private $_age;
public void age($new_age) {
$this->_age = $new_age;
}
到
private $_age;
public void age($new_age) {
if ($new_age > 0) {
$this->_age = $new_age;
}
}
您不必触及set_age方法的单个使用者;变化“只是工作”。这就是OOP的真正美:你可以在一次方法调用后隐藏很多实现细节。
封装也可以在其他地方提供帮助:假设你想要一个记录每个年龄变化的Person的子类。使用setter方法,它就像覆盖一样简单;通过直接变量访问,这将是一团糟。
答案 1 :(得分:4)
通过提供访问器(setter / getter方法,或者使用支持它们的语言中的属性,如C#),开发人员可以在类及其用户之间定义更稳定的契约。通过实际读取或写入存储器位置而不是直接访问字段,用户被迫调用方法,而方法又可以封装任何必要的逻辑。
反过来,当修改班级的内部设计时,其合同需要不经常更改。因此,代码的可维护性和稳定性得到了改善。
请注意,性能不是问题,因为现代JIT编译器能够以消除实际调用的方式优化对普通getter / setter的调用,并且代码等同于直接访问底层内存位置。
修改强>
此外,setter和getter通常可以具有不同的可见性(公共/受保护/私有),为指定值上的读/写操作提供更细粒度控制的额外好处。
因此,最佳做法是尽可能避免使用公共字段,而是使用setter / getter方法或属性。
答案 2 :(得分:0)
让你不要破坏它,防止其他人破坏它,并表达非公众成员不属于他人应该看到的东西的想法 - 正在实现Encapsulation。
答案 3 :(得分:0)
好吧,我认为set / get方法可以帮助更好地保护属性,就好像你直接改变这个值可能会导致一些麻烦,例如:对代码有害。我认为set / get为用户提供了一种方法,而不是直接对attributs进行操作。
答案 4 :(得分:0)
protected关键字经常被误解,甚至可能被过度使用。简而言之,受保护的成员用于与子类进行通信,而公共成员用于 与呼叫者交流。