您好我想知道为什么一些流行的PHP库会保护所有属性,然后为它们添加get和set方法,如:
protected
$a = false;
public function getA(){
return $this->a;
}
public function setA($value){
$this->a = (bool)$value;
}
这有什么好处,为什么不简单地公开财产呢?
答案 0 :(得分:4)
OOP现实世界情景:
想象一下,您有一个班级Vehicles
,他们有(protected
)wheels
。您的Vehicles
与wheels
不同,但addWheel
与Bike
不同,addWheel
与Aircraft
不同。
代码优势:
使用getter和setter,您可以使用typehinting
。
比较这些摘要:
class Car {
public $wheels;
}
$bmw = new Car;
$bmw->wheels = 'piece of paper';
上面的代码允许您添加任何内容wheel
,但是您可以使用一张纸作为方向盘吗?
现在有了getter和setter:
class Car {
protected wheels;
public function __construct() {
$this->wheels = new ArrayIterator;
}
public function addWheel(Wheel $wheel) {
$this->wheels->add($wheel);
return $this;
}
public function removeWheel(Wheel $wheel) {
$this->wheels->remove($wheel);
return $this;
}
}
class Wheel {
}
$bmw = new Car;
$bmw->addWheel('piece of paper'); // <-- throws an error!
// paper cannot be used as a wheel
$bmw->addWheel(new Wheel); // <-- good :-)
更多代码,更直接。想象一下,您有RearWheels
和FrontWheels
:
class Wheel {
}
class FrontWheel extends Wheel {
}
class RearWheel extends Wheel {
}
class Car {
protected wheels;
public function __construct() {
$this->wheels = new ArrayIterator;
}
public function addWheel(Wheel $wheel) {
// check for already existing Wheels here.
// Pseudo Code:
if (wheels typeof RearWheel > 2) {
throw new Exception('cannot add more than 2 RearWheels to the Car');
}
return $this;
}
public function removeWheel(Wheel $wheel) {
$this->wheels->remove($wheel);
return $this;
}
}
答案 1 :(得分:2)
它允许您添加自定义setter和getter以防您想要添加额外的功能,并且有时也用于跟踪“脏”状态(如果对象自从DB加载后已更改)。 / p>
这也是因为PHP没有只读属性的“本机”语法。
<强>增加:强> 在我的原始答案中,我没有完全明白我的观点,在许多情况下,由于PHP的工作原理。
考虑这个PHP示例,我们使用元编程来动态调用自定义setter。
class Foo {
protected $bar;
// use some metaprogramming magic to automatically call setter
public function __set($key, $val){
$setter = "set".ucfirst($key);
if (method_exists($this, $setter)){
$this->$setter($val);
}
else {
throw new Exception("$key value cannot be set, looking for $setter in ".get_class($this));
}
}
// enforce the Type of bar
public function setBar(String $val){
$this->bar = $val;
}
}
$foo = new Foo();
// this should fail
$foo->bar = 12;
// Catchable fatal error: Argument 1 passed to Foo::setBar() must be an instance of String, integer given
我试图在这里得到的是,你不是一个糟糕的程序员拥有公共属性,而是大多数PHP框架都避开PHP对象模型,需要保护属性以继承和反射工作很多情况。
答案 2 :(得分:1)
支持其类扩展或继承的流行库使其字段受到保护。这是OOP的概念,必须在数据方面进行抽象和封装。不允许每个人直接访问数据。只有类的成员才能访问其数据。这是因为字段被标记为受保护,因此只有继承的类对象或相同类的对象才能访问数据。所有其他人必须使用get和set方法来获取数据。保持代码管理,清洁和安全。