Corey
Corey

Reputation: 826

How do private and protected members function in PHP OOP?

I am confused by the following statement...

Members declared protected can be accessed only within the class itself and by inherited and parent classes. Members declared as private may only be accessed by the class that defines the member.

Is this a matter of instantiated objects at runtime accessing members of other objects, or is this about governing what's allowed when overriding parent class members in children?

If it's the former, does that mean if two objects are of the same type, they can access each-others members that are “protected”. If so, how would they do that?

Upvotes: 2

Views: 831

Answers (5)

Sebastien C.
Sebastien C.

Reputation: 4833

If my understanding of your question is good, the answer is yes. The access depends on the class, not on the instance.

The documentation (http://php.net/manual/en/language.oop5.visibility.php) says :

Objects of the same type will have access to each others private and protected members even though they are not the same instances. This is because the implementation specific details are already known when inside those objects.

That means that this will work and print "It works !" :

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

Upvotes: 0

bishop
bishop

Reputation: 39354

  • Public describes information shareable between objects of unrelated classes.
  • Protected describes information shareable between objects of this class and its children.
  • Private describes information available only to a single class of objects.

Upvotes: 0

deceze
deceze

Reputation: 521995

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
    }

}

Any class in the same hierarchy can access protected methods.
Only the declaring class itself can access private methods.
Both are not restricted to $this, it applies to any object within the context of the class.

The rational to keep in mind here is that a class should know about its own implementation, hence can be trusted to call its own methods appropriately/access its own properties appropriately. It doesn't matter if the class does that just on itself or on other objects of the same type. The idea being that you want to keep complex functionality or half-baked code from being used all over the place. By making it protected you at least ensure that only closely related code can make calls to it, while private keeps the calls even more localised. You should only expose as much code to a "wider audience" as is necessary to make the class useful. Keep everything else encapsulated within the class to ensure your future flexibility to mess around with it.

Upvotes: 2

GolezTrol
GolezTrol

Reputation: 116100

Visibility in order of low to high:

  • private: can be used/called only from methods within that actual class.
  • protected: can be used/called from methods in that class and descendants of that class.
  • public: can be used/called from anywhere. Callable from 'the outside world'.

Like this:

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();

Upvotes: 1

andrew
andrew

Reputation: 9583

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

Upvotes: 1

Related Questions