是否需要保护所有物业?

时间:2014-10-05 16:37:00

标签: php class oop

您好我想知道为什么一些流行的PHP库会保护所有属性,然后为它们添加get和set方法,如:

  protected
    $a = false;

  public function getA(){
    return $this->a;
  }

  public function setA($value){
    $this->a = (bool)$value;
  }

这有什么好处,为什么不简单地公开财产呢?

3 个答案:

答案 0 :(得分:4)

OOP现实世界情景:

想象一下,您有一个班级Vehicles,他们有(protectedwheels。您的Vehicleswheels不同,但addWheelBike不同,addWheelAircraft不同。

代码优势:

使用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 :-)

更多代码,更直接。想象一下,您有RearWheelsFrontWheels

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方法来获取数据。保持代码管理,清洁和安全。