首先,当你开发strong-OO 类时,你应该尽可能少地暴露你的类的内部语义(显然不影响功能)。
一些变量仅在类本身的上下文中才有价值,并且对于使用该类的开发人员来说毫无意义。将变量公开允许使用该类的任何人随意更改此类变量,尽管他们可能不知道它的用途。在 PHP 中,当您甚至没有类型安全来至少减轻可以造成的损害时,这可能是一个特殊的问题。
考虑一下:您有一个包含一些 I/O 操作的类。让我们称之为FileReader
class FileReader {
public $_handle;
public function __construct($filepath) {
$this->_handle = fopen($filepath, 'r');
if ($this->_handle === NULL) {
throw new Exception("Unable to open the file for reading");
}
}
// ... the rest of the class
}
现在您可以看到该类打开了一个文件句柄。通过将$_handle
变量公开,您已将其公开给在您的班级工作的所有人员。他们不需要知道您打开的原始文件句柄,他们只想使用您的好类来执行一些读取操作。但是,它是公开的;他们不仅可以看到它,而且可以改变它。这很糟糕,尤其是当您的其他代码假定$_handle
变量有效时。
$reader = new FileReader();
$reader->_handle = "I hope this doesn't break anything. /trololol";
$reader->someOperation(); // oh no! Our file handle has just been changed to something completely wrong, this is now going to the break the class.
通过首先将变量设为私有,可以完全避免这种荒谬的情况。有关每个访问修饰符的作用以及何时应用它们的更多(更好)示例,请参见此答案。
现在,进入 getter 和 setter。在您的问题中,您似乎假设所有 getter 和 setter 都按以下方式编写:
class Foo {
private $_bar;
public function getBar() {
return $this->_bar;
}
public function setBar($newBar) {
$this->_bar = $newBar
}
}
$_bar
在这种情况下,您是绝对正确的,这与首先将变量更改为公共没有区别。
但是,getter 和 setter 方法使您可以控制外部开发人员如何设置变量,因此您可以立即检测它们何时会发出嘘声并避免以后出现未定义的行为。例如:
class Foo {
private $_bar;
public function getBar() {
return $this->_bar;
}
public function setBar($newBar) {
// Now we're going to ensure that $newBar is always an integer
if (!is_int($newBar)) {
// not an integer, throw out an exception to let the developer know that somewhere is setting invalid input
throw new Exception("Expected an integer value for 'Bar'");
}
$this->_bar = $newBar;
}
}
这不仅使您的类更加健壮,而且使使用您的类的开发人员的生活变得更加轻松。当类尝试使用 的损坏值时,不必稍后在某个地方调试一个极其奇怪的问题$_bar
,他们可以很容易地从堆栈跟踪中判断损坏值是从哪里设置的,并从源头修复它。
有大量关于变量访问和 getter/setter 方法的文档,它适用于各种语言,所以不要害怕查找基于 C++/C#/VB.NET 的文章,它们都大致翻译成相同的材料。