Change the value of a protected variable for child class
I'm trying to do something that I thought would be quite simple but as I am relatively new to OOP in PHP I'm having a bit of trouble.
Here is my code :
<?php
class MyClass
{
protected $variable = 'DEFAULT';
function __construct($newVariable)
{
$this->variable = $newVariable;
echo $this->variable;
}
}
class OtherClass extends MyClass
{
function __construct()
{
echo $this->variable;
}
}
$foo = new MyClass('MODIFIED'); // Output : MODIFIED
$bar = new OtherClass(); // Output : DEFAULT
?>
I searched a lot of different threads and websites but haven't found how I could possibly pass the redefined value of $variable to the child class. Can someone guide me through it ? If there's a way.
Thanks in advance.
EDIT Clarifying what is actually happening in the script I'm having this problem : I have a class that creates a form, and in that class there are several variables telling the functions in what environnement we are : if it's a multilanguage form or not, if I want a plain form or a structured one, parameters like that. And some of these environnement variables are m开发者_Go百科odified through the execution of the class, by its functions.
Now, because of the needs of my page, I have a child class dedicated to creating "select" fields. It inherits the core function of the main class to create fields and such but the child class takes several more parameters. Thing is, I would still like the select class to inherits the environnement parameters from the main class, in the state they are.
As I'm typing this I realize the way I approached it may not be the right way to do it because when I look at my code I think there might be another way to do that. In my code I have two objects where I would need it to be only one, but I don't really know how I would put that actually.
You're not redefining the variable, you're just setting it in the parents constructor. Call it and you've got what you need (see the comment in the code, it's one line only):
<?php
class MyClass
{
protected $variable = 'DEFAULT';
function __construct($newVariable)
{
$this->variable = $newVariable;
echo $this->variable;
}
}
class OtherClass extends MyClass
{
function __construct()
{
parent::__construct(); # <<--- do this
echo $this->variable;
}
}
$foo = new MyClass('MODIFIED'); // Output : MODIFIED
$bar = new OtherClass(); // Output : MODIFIED
?>
Even if you have two classes definition, the concrete instance will always be of one class. That one class can inherit from a parent class, but if you override methods (like you did with the constructor), the parents class method will not be called because it has been overridden. However with the parent
keyword you can access a parent's method from within the child.
The constructor of MyClass
is overridden in OtherClass
. The parent constructor does not implicitly automatically run. If you want to run the parent constructor as well, call parent::__construct()
in OtherClass::__construct
.
You'll of course have a problem here, since MyClass::__construct
expects a parameter while OtherClass::__construct
doesn't have one. Putting it like this, how did you expect the value to change…?
The child class only inherits methods and default variables. It does not inherit the root class's properties if you start a new instance, because $foo
and $bar
are two different objects.
You'll have to do $bar = new OtherClass("MODIFIED");
and then, add parent::__construct($newVariable)
to the second __construct, too. (and the respective parameter)
Basically, you can't expect a new instance (which is parallel to the $foo one) to "magically" inherit a modified one from the original $foo. You have to find a way to pass it (therefore, calling the parent constructor).
You need to add a call to parent
in the child class:
function __construct()
{
parent::__construct();
echo $this->variable;
}
You can do that with any function:
function doSomethingAWESOME()
{
parent::doSomethingAWESOME();
echo "I think that was awesome";
}
And basically, the statement amounts to, "You know everything you were going to do in the parent class before I overrode it? Yea, do that here."
Also cool:
function doSomethingAWESOME()
{
echo "NEVER!!!";
}
function parentSomethingAwesome()
{
// calls the parent class's definition of some doSomethingAWESOME
parent::doSomethingAWESOME();
}
What you want to do is not possible as-is: $foo and $bar are instances of your classes so there are no links between them.
To use the construction analogy, your two classes are like building plans: the plan of a house, and the plan of a house with a garage. What you're trying to do is like you build a house (instance a class), put some kind of bed in it (set some variables) and when you build another house with a garage you want the same bed in it. It's not gonna happen.
Basically, the other class is not inheriting the update by the construct in the parent class.
How about you just pass in 'MODIFIED'
arg in the child class too and initialize it with construct. Because foo and bar are two different instances (thou of the same class), but they are not linked together.
精彩评论