你好,我想知道爲什麼一些流行的PHP庫,讓所有屬性的保護,再加入獲得,併爲他們設置的方法,如:是否需要保護所有屬性?
protected
$a = false;
public function getA(){
return $this->a;
}
public function setA($value){
$this->a = (bool)$value;
}
什麼是這樣做的好處,爲什麼不乾脆讓公共財產?
你好,我想知道爲什麼一些流行的PHP庫,讓所有屬性的保護,再加入獲得,併爲他們設置的方法,如:是否需要保護所有屬性?
protected
$a = false;
public function getA(){
return $this->a;
}
public function setA($value){
$this->a = (bool)$value;
}
什麼是這樣做的好處,爲什麼不乾脆讓公共財產?
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
,但你可以使用一張紙作爲車輪?
現在:
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
:爲什麼使用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;
}
}
它允許您添加自定義設置器和獲取器,以防您想添加額外功能,並且有時也用於跟蹤「髒」狀態(如果對象自從從數據庫加載後發生更改)。
這也是由於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對象模型周圍閃避被保護和傳承反射在許多情況下工作。
支持其類的擴展或繼承的流行庫使其字段受到保護。這就是OOP的概念,就數據而言必須有抽象和封裝。不允許每個人直接訪問數據。只有班級成員才能訪問其數據。這是原因字段被標記爲保護,以便只有繼承類的對象或同一類的對象才能訪問數據。所有其他人都必須使用get和set方法來獲取數據。保持代碼管理,清潔和安全。
有是說,包含了所有的數據沒有金科玉律在一個對象中必須受到保護或其「糟糕的」OOP。它更多的是由於PHP對象模型的工作原理。 Ruby例如具有每個屬性get/set/readonly方法和大型庫,如Mongoid和OpenRecord使用公共屬性。 – max 2014-10-05 16:50:53
對不起ActiveRecord,不是OpenRecord – max 2014-10-05 18:21:28
是的,你是對的,沒有黃金法則的一切都必須得到保護。它是用於抽象的OOP中提供的一個選項。根據課堂數據的性質,在課堂上可以有公衆也可以有私人成員。 – 2014-10-05 18:41:00
的可能重複(https://stackoverflow.com/questions/1568091/why-use-getters-and-setters) – Boann 2014-10-05 16:39:48
這裏有一個偉大的答案:爲什麼使用getter和setter] [1] [1]:http://stackoverflow.com/a/1568230/3916476 – tenhsor 2014-10-05 16:42:15