2014-03-28 54 views
2

我對下面的語句混淆...私人和受保護成員如何在PHP OOP中運行?

聲明爲受保護成員只能在類 本身和繼承和父類訪問。聲明爲 private的成員只能由定義該成員的類訪問。

這是一個在運行時訪問其他對象的成員的實例化對象的問題,或者這是關於控制什麼是允許在兒童重寫父類成員時允許的問題?

如果是前者,這是否意味着如果兩個對象都是同一類型的,他們可以訪問每一個,其他成員是「受保護」。如果是這樣,他們將如何做到這一點?

+0

可能相關的小記事。僅僅因爲你聲明瞭一個私有或受保護的方法,並不意味着使用它的人將無法得到值或使用它們(通過將它們轉換爲數組)。 –

回答

1

能見度的低位到高位:

  • 私人:可用/只從實際的類內的方法調用。
  • protected:可以從該類中的方法和該類的後代使用/調用。
  • public:可以在任何地方使用/調用。可從'外部世界'中調用。

像這樣:

class Parent { 
    public function publicMethod(){ echo "Base:publicMethod"; } 

    protected function protectedMethod(){ echo "Base:protectedMethod"; } 

    private function privateMethod(){ echo "Base:privateMethod"; } 
} 

class Child extends Parent { 
    function Test() 
    { 
    // This will work. 
    $this->publicMethod(); 
    // This will work. Child can call protected method of parent. 
    $this->protectedMethod(); 
    // This will fail. It won't work for privates. 
    $this->privateMethod(); 
    } 
} 

$p = new Parent(); 
$c = new Child(); 

// The next two lines will succeed. You can call the public method, even 
// if it is declared in a parent class of the one you are calling: 
$p->publicMethod(); 
$c->publicMethod(); 

// The next lines will fail. You call private or protected methods outside of 
// the class even though $p and $c point to instances of those classes. 
$p->protectedMethod(); 
$c->protectedMethod(); 
$p->privateMethod(); 
$c->privateMethod(); 
2
class Foo { 

    protected function protector() { 
     $this->privateEye(); // works 
    } 

    private function privateEye() { 
     ... 
    } 

} 

class Bar extends Foo { 

    public function baz() { 
     $this->protector(); // works 
     $this->privateEye(); // fails 

     $obj = new self; 
     $obj->protector(); // works 
     $obj->privateEye(); // predictably fails as well 
    } 

} 

在同一層級可以訪問protected方法的任何類。
只有聲明類本身可以訪問private方法。
兩者都不僅限於$this,它適用於該類的上下文內的任何對象。

這裏要記住的理由是一個類應該知道它自己的實現,因此可以被信任調用它自己的方法適當地/適當地訪問它自己的屬性。如果類只是在自己或其他相同類型的對象上執行,那並不重要。這個想法是,你想要保持複雜的功能或不完整的代碼在整個地方被使用。通過使protected您至少確保只有密切相關的代碼可以撥打電話,而private保持呼叫更加本地化。您應該只向必要的「更廣泛的讀者」展示儘可能多的代碼,以使課程有用。將所有其他內容封裝在課堂上,以確保您未來的靈活性能夠解決問題。

+0

好的解釋和很好的附加細節,把它放在上下文中。 – GolezTrol

0
  • 公共描述無關的類的對象之間共享信息。
  • 受保護描述了此類別的對象與其子女之間可共享的信息
  • 私人描述的信息僅適用於單一類別的對象
+0

其他人也說了一句話。我喜歡「單一類對象」一詞,但不喜歡「同一類層次結構的對象」。它表明它是雙向的,顯然不是這種情況。 – GolezTrol

+0

是的,但是我只是在*之後給出了單詞*。更好? – bishop

1
class foo{ 
    public foo; 
    protected bar; 
    private baz; 

    function __construct(){ 
     $this->foo=1; 
     $this->bar=2; 
     $this->baz=3; 
    } 
} 


class bar extends foo{ 

} 

$foo = new foo(); 
$bar = new bar(); 

echo $foo->foo; //ok 
echo $foo->bar; //ok 
echo $foo->baz; //ok 


echo $bar->foo; // ok 
echo $bar->bar; // ok 
echo $bar->baz; //not ok 

enter image description here

+0

回聲受保護或私有變量不起作用,或者我錯過了什麼? –

0

如果我對你的問題的理解是不錯的,答案是肯定的。訪問取決於類,而不是實例。

文檔(http://php.net/manual/en/language.oop5.visibility.php)說:

同一類型的對象將有機會獲得對方的私有和保護成員,即使他們是不一樣的情況。這是因爲實現特定的細節在這些對象內部時是已知的。

這意味着這將工作和打印「它的工作!」 :

class Baz { 
    private $foo; 
    protected $bar; 

    public function __construct($foo, $bar) { 
     $this->foo = $foo; 
     $this->bar = $bar; 
    } 

    public function isFooEqual(Baz $b) { 
     return ($this->foo == $b->foo); 
    } 

    public function isBarEqual(Baz $b) { 
     return ($this->bar == $b->bar); 
    } 
} 

$x = new Baz("Hello", "World"); 
$y = new Baz("Hello", "World"); 

if($x->isFooEqual($y) && $x->isBarEqual($y)) { 
    echo "It works !"; 
} else { 
    echo "Fail"; 
}