2014-10-05 93 views
0

你好,我想知道爲什麼一些流行的PHP庫,讓所有屬性的保護,再加入獲得,併爲他們設置的方法,如:是否需要保護所有屬性?

protected 
    $a = false; 

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

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

什麼是這樣做的好處,爲什麼不乾脆讓公共財產?

+1

的可能重複(https://stackoverflow.com/questions/1568091/why-use-getters-and-setters) – Boann 2014-10-05 16:39:48

+0

這裏有一個偉大的答案:爲什麼使用getter和setter] [1] [1]:http://stackoverflow.com/a/1568230/3916476 – tenhsor 2014-10-05 16:42:15

回答

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:爲什麼使用getter和setter]

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; 
    } 
} 
2

它允許您添加自定義設置器和獲取器,以防您想添加額外功能,並且有時也用於跟蹤「髒」狀態(如果對象自從從數據庫加載後發生更改)。

這也是由於PHP沒有用於只讀屬性的「本地」語法。

此外: 在我的原始答案中,我沒有完全明白我的觀點,即在許多情況下,由於PHP的工作原理。

考慮這個PHP示例,我們使用元編程來動態調用自定義設置器。

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對象模型周圍閃避被保護和傳承反射在許多情況下工作。

1

支持其類的擴展或繼承的流行庫使其字段受到保護。這就是OOP的概念,就數據而言必須有抽象和封裝。不允許每個人直接訪問數據。只有班級成員才能訪問其數據。這是原因字段被標記爲保護,以便只有繼承類的對象或同一類的對象才能訪問數據。所有其他人都必須使用get和set方法來獲取數據。保持代碼管理,清潔和安全。

+0

有是說,包含了所有的數據沒有金科玉律在一個對象中必須受到保護或其「糟糕的」OOP。它更多的是由於PHP對象模型的工作原理。 Ruby例如具有每個屬性get/set/readonly方法和大型庫,如Mongoid和OpenRecord使用公共屬性。 – max 2014-10-05 16:50:53

+0

對不起ActiveRecord,不是OpenRecord – max 2014-10-05 18:21:28

+0

是的,你是對的,沒有黃金法則的一切都必須得到保護。它是用於抽象的OOP中提供的一個選項。根據課堂數據的性質,在課堂上可以有公衆也可以有私人成員。 – 2014-10-05 18:41:00

相關問題