什么时候以及为什么我应该在类中使用公共、私有和受保护的函数和变量?它们之间的区别是什么?
例子:
// Public
public $variable;
public function doSomething() {
// ...
}
// Private
private $variable;
private function doSomething() {
// ...
}
// Protected
protected $variable;
protected function doSomething() {
// ...
}
对我来说,这是理解这三种属性类型最有用的方法:
Public:当您可以在代码中的任何地方直接访问和更改此变量时,使用此选项。
类外部的示例用法:
$myObject = new MyObject()
$myObject->publicVar = 'newvalue';
$pubVar = $myObject->publicVar;
Protected:当你想强迫其他程序员(和你自己)在访问和设置变量时在类外部使用getter /setter时使用这个选项(但你应该保持一致,在类内部也使用getter和setter)。This或private往往是设置所有类属性的默认方式。
为什么?因为如果你决定在未来的某个时候(可能甚至在5分钟内),你想要操作该属性返回的值,或者在获取/设置之前对它做一些事情,你可以这样做,而无需重构你在项目中使用它的所有地方。
类外部的示例用法:
$myObject = new MyObject()
$myObject->setProtectedVar('newvalue');
$protectedVar = $myObject->getProtectedVar();
Private:私有属性与受保护属性非常相似。但显著的特点/区别是,将其设为私有也使得子类无法访问它,而无需使用父类的getter或setter。
因此,基本上,如果你正在为一个属性使用getter和setter(或者如果它只在父类内部使用,并且它并不意味着在其他任何地方都可以访问),你最好将它设置为私有,只是为了防止任何人试图直接使用它并引入错误。
在子类(扩展MyObject)中的使用示例:
$this->setPrivateVar('newvalue');
$privateVar = $this->getPrivateVar();
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // Works
echo $obj->protected; // Fatal Error
echo $obj->private; // Fatal Error
$obj->printHello(); // Shows Public, Protected and Private
/**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// We can redeclare the public and protected method, but not private
protected $protected = 'Protected2';
function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj2->public; // Works
echo $obj2->private; // Undefined
echo $obj2->protected; // Fatal Error
$obj2->printHello(); // Shows Public, Protected2, Undefined
摘录自:
http://php.net/manual/en/language.oop5.visibility.php
又提了一个老问题,但我认为从你所定义的API的角度来考虑这个问题是一个很好的方法。
public——所有标记为public的东西都是API的一部分,任何使用你的类/接口/其他的人都会使用和依赖它。
protected -不要被愚弄了,这也是API的一部分!人们可以子类化,扩展你的代码,使用任何标记为受保护的东西。
private -私有属性和方法可以随心所欲地更改。没有其他人可以使用这些。这些是唯一可以在不进行破坏性更改的情况下进行更改的内容。
或者用Semver的话说:
对任何公共或受保护的内容的更改都应被视为重大更改。
任何新的公开或受保护的内容(至少)都应该是MINOR
只有对任何私有内容的新/更改才能被PATCH
因此,在维护代码方面,注意哪些内容是公开的或受保护的,因为这些是你向用户承诺的内容。