|
|
PHP OOP question
|
|
|
|
Dedicated MacNNer
Join Date: Aug 2002
Status:
Offline
|
|
I was getting some bugs i wasn't expecting, setup this test case, and still don't get what's going on. if anyone can clarify what's happening here, that would be great.
[PHP]
class a
{
private $prop=-1;
function __construct() {
$this->prop=0;
}
function getprop() {
return $this->prop;
}
}
class b extends a
{
function __construct() {
$this->prop=1;
}
}
class c extends a
{
function __construct() {
$this->prop=1;
}
function getprop() {
return $this->prop;
}
}
$a = new a();
echo($a->getprop()); // 0
$b = new b();
echo($b->getprop()); // -1
$c = new c();
echo($c->getprop()); // 1
[/PHP]
gives me the output
0 -1 1
so why does overloading the getprop method cause php to update the private property?
|
|
|
|
|
|
|
|
|
Grizzled Veteran
Join Date: Oct 2003
Status:
Offline
|
|
Originally Posted by clam2000
so why does overloading the getprop method cause php to update the private property?
It doesn't.
"Private limits visibility only to the class that defines the item."
If you want your child classes to have direct access to the private properties/methods, you need to use protected, not private.
In the b and c class constructors, when you are doing $this->prop = 1, you are actually creating a new public property, "prop". You can verify this with print_r or var_dump:
Code:
php > $c = new c();
php > print_r($c);
c Object
(
[prop: private] => -1
[prop] => 1
)
php >
So, c::getprop is actually returning the public prop of object c.
The same is true of b as well. It has the private prop (which it cannot see), and a public prop from the constructor. But b::getprop is actually a::getprop. a has access to the private prop, so it returns that and not the public prop of b.
It has to do with visibly. You aren't changing the private property of a, but are creating a new public property.
We can go one further to help demonstrate this:
[php]class d extends a
{
function getprop() {
return $this->prop;
}
}[/php]
Code:
php > $d = new d();
php > echo $d->getprop();
PHP Notice: Undefined property: d::$prop in php shell code on line 4
Notice: Undefined property: d::$prop in php shell code on line 4
php >
Here we get a warning, because d cannot see the private prop, and we've not set a public one either.
It does seem a bit odd, but I don't think it is a bug. Normally you cannot have properties of the same name in a class even with different visualities. However, in b & c, they cannot see the property "prop" since it is private to a, so you can redeclare it, which is basically what is going on with your test code.
I tend to stay away from private as there is really no example I can think of where you would want to shield properties or methods from child classes, so mostly I stick to protected and public.
|
The only thing necessary for evil to flourish is for good men to do nothing
- Edmund Burke
|
|
|
|
|
|
|
|
Dedicated MacNNer
Join Date: Aug 2002
Status:
Offline
|
|
that's sort of what i figured was happening.
i just was sort of confused that php was auto creating a property I hadn't defined without generating any sort of warning.
--Will
|
|
|
|
|
|
|
|
|
Grizzled Veteran
Join Date: Oct 2003
Status:
Offline
|
|
Originally Posted by clam2000
i just was sort of confused that php was auto creating a property I hadn't defined without generating any sort of warning.
PHP is a bit more relaxed than other languages. Variables, including object properties, do not need declared/defined before you assign them a value... you can basically think of it as assigning a variable a value also declares/defines it... so you can dynamically create object properties (and methods as well with some tricks), which can come in really handy for all kinds of things (for example a generic "settings" object that stores program settings as properties).
However, you should assign them before using them (or if you are unsure, check that they are set using isset()). It does generate a notice if you don't, just like in the class d example, "PHP Notice: Undefined property". And trying to use an undefined variable will result in a "PHP Notice: Undefined variable"
To make life easier, I find it is best to always declare any class properties. Remember private properties/methods are only visible to the class that declares them, so even though child classes *technically* do inherit them, they cannot see them (cannot read them and cannot write them). And again, I personally find it is best to avoid private when having parent/child classes and stick to protected/public in those cases. I think if you need to hide something the parent has from a child, there is probably a better way to approach the issue.
(
Last edited by madmacgames; Dec 29, 2005 at 09:27 PM.
)
|
The only thing necessary for evil to flourish is for good men to do nothing
- Edmund Burke
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Forum Rules
|
|
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
|
|
|
|
|
|