Reputation: 826
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
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
Reputation: 39354
Upvotes: 0
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
Reputation: 116100
Visibility in order of low to high:
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
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
Upvotes: 1