Could someone explain me, why is it possible to do the following in PHP, but, for example, not in C# or Java:
Class A {
protected $a = 'Howdy!';
}
Class B extends A {
public function howdy() {
$created = new A();
echo $created->a; <----- This is legal due to per-class visibility
}
}
$b = new B();
echo $b->howdy(); <----- Hence, no fatal error here
This behavior seems to be specified here, but I can't understand the fundamental reason behind this (to my mind, one can't simply implement the per-class
visibility instead of the per-instance
one without having a strong reason for that).
It is possible to do in both C# and Java as well.
protected
means the variable is accessible from any subclass of A. B is a subclass of A, hence it can access the variable. There's no magic here.The reason it doesn't work is, as you specified, PHP implements access control on a class level, where other languages use an instance level approach.
Why is it useful? It allows your classes to operate on other instances of itself without exposing its private data. Let's take a simple value-object example:
This lets you keep protected info encapsulated, yet still work with it across instances...
There are pros and cons to both approaches...
The page you linked to has a section titled "Visibility from other objects" which states that:
That is also possible in C# (and Java for that matter).
Basically what is going on is this:
a
which means it is visible in the scope of classes which extend A (in our case class B)a
)It wouldn't work if you'd done this:
In your example, you're not accessing the $a member direct from B(). You're accessing it from an A() object that happens to have been instantiated from inside B().