I created an extended class in order to modify a protected var for particular purpose. However I don't understand how I can modify a parent class protected var from a child class and use it everywhere in the parent functions.
For example:
class parent {
protected $data;
public function __construct() {
add_action('wp_ajax_output', array(&$this, 'output'));
}
public function output() {
get_data();
show();
}
public function get_data() {
$this->$data = 'data_1';
}
public function show() {
// here I'm using the protected var (I would like to use it from child)
echo $this->data;
}
}
new parent();
class child extends parent {
public function __construct() {
parent::__construct();
add_action('wp_ajax_child_output', array(&$this, 'child_output'));
}
public function child_output() {
$this->data = 'data_2';
// I would like to use $this->data in parent::show();
parent::show();
}
}
new child();
How can I override all protected var use in parent?
I've just tested your code and it gives out correct output. Issue lies somewhere else.
when you use child_output() you use it correctly. All protected properties are accessible directly through a child class as well as all protected,public methods.
if you create an object from the parent class then you are using the parent class as it is. If you create an object from the child class then it inherits all properties and methods from the parent class, thus child class has a property $data and three extra methods
Related
See the following example (PHP)
class Parent
{
protected $_property;
protected $_anotherP;
public function __construct($var)
{
$this->_property = $var;
$this->someMethod(); #Sets $_anotherP
}
protected function someMethod()
...
}
class Child extends Parent
{
protected $parent;
public function __construct($parent)
{
$this->parent = $parent;
}
private function myMethod()
{
return $this->parent->_anotherP; #Note this line
}
}
I am new to OOP and am a bit ignorant.
Here to access the parents property I am using an instance of that class, which seems wrong :S (no need of being i child then). Is there an easy way, so that i can sync the parent properties with the child properties and can directly access $this->anotherP without having to use $this->parent->anotherP ?
As your Child class is extending your Parent class, every properties and methods that are either public or protected in the Parent class will be seen by the Child class as if they were defined in the Child class -- and the other way arround.
When the Child class extends the Parent class, it can be seen as "Child is a Parent" -- which means the Child has the properties of the Parent, unless it redefines those another way.
(BTW, note that "parent" is a reserved keyword, in PHP -- which means you can't name a class with that name)
Here's a quick example of a "parent" class :
class MyParent {
protected $data;
public function __construct() {
$this->someMethodInTheParentClass();
}
protected function someMethodInTheParentClass() {
$this->data = 123456;
}
}
And it's "child" class :
class Child extends MyParent {
public function __construct() {
parent::__construct();
}
public function getData() {
return $this->data; // will return the $data property
// that's defined in the MyParent class
}
}
That can be used this way :
$a = new Child();
var_dump($a->getData());
And you'll get as output :
int 123456
Which means the $data property, defined in the MyParent class, and initialized in a method of that same MyParent class, is accessible by the Child class as if it were its own.
To make things simple : as the Child "is a" MyParent, it doesn't need to keep a pointer to... itself ;-)
This may save you a few hours of searching around.
Remember: Your Child class only inherits the properties DEFINED in the Parent class... So if you instantiate an object using Parent class and then populate it with data, then this data will NOT be available in your child class...
It's super obvious of course, but I'm guessing others may run into the same issue.
A super simple solution is not to extend anything, simply pass the $object of your parent class into your child class through a constructor. This way you have access to all the properties and methods of the object generated by parent class
Example
class child {
public parentObject;
public function __construct($parentObject) {
$this->parentObject = $parentObject;
}
}
If your $parentObject has a public property $name, then you can access it inside the child class with a function like:
public function print_name() {
echo $this->parentObject->name;
}
here is the class structure. I want Observer:callme() to be callable from Children too.
class Observer
{
protected callme()
{
}
}
class Parent extends Observer
{
function createChild()
{
$this->callme(); // this is OK
return new Child ($this);
}
}
class Child
{
private $this myParent;
public function __constructor ($myParent)
{
$this->myParent = $myParent;
}
public function __destroy()
{
$this->myParent->callme(); // FAIL!
}
}
so how to make FAIL work? (without making it public, because its only for used inside "Parent" and its "Children")
The problem is that a protected method is only accessed from the same class or the class children. What you can do is extend your Child class from Parent, like this:
class Child extends Parent
{
public function __constructor ()
{
parent::__constructor();
}
public function __destroy()
{
$this->callme(); // Should work!
}
}
Or just change the method to public.
And, btw, is this code some kind of real code that you will use? That constructor receiving the parent object seems to be so wrong. What are you trying to accomplish?
protected means that you can call that method only from the same class and from subclasses. What you want to do is not possible. The protected keyword would be pointless if you could call these methods from everywhere.
In C++ there is the friend keyword to achieve what you want: you could define Child as friend of Observer (this has to be done from within Observer), and then you can call all methods in Observer (including private and protected) from within methods of Child. But such a keyword does not exist for PHP.
My comment on your question explains why it doesn't work. This answer shows a way to accomplish what you asked based upon your clarification that MyChild should not extend MyParent.
This is a hack example that makes it work by exploiting the fact that php doesn't care if you call protected methods on other instances than yourself as long as you share the ancestor of the protected method.
I had to change the code some to make it valid php. __constructor is not the name of a php constructor.
hacky.php
<?php
class Observer
{
protected function callme()
{
echo 'I was called from ' . get_called_class(), PHP_EOL;
}
}
class MyParent extends Observer
{
public function createMyChild()
{
$this->callme(); // this is OK
return new MyChild ($this);
}
}
class MyChild extends Observer // hackey extends
{
private $myMyParent;
public function __construct($myMyParent)
{
$this->myMyParent = $myMyParent;
$this->myMyParent->callme();
}
}
$p = new MyParent;
$c = $p->createMyChild();
Result:
$ php hacky.php
I was called from MyParent
I was called from MyParent
I think I found the solution:
class Parent extends Observer
{
function createChild()
{
$this->callme(); // this is OK
return new Child (function() { $this->callme(); });
}
}
class Child
{
private $gatewayFunction;
public function __constructor (Closure $gatewayFunction)
{
$this->gatewayFunction = $gatewayFunction;
}
public function __destroy()
{
$this->gatewayFunction->__invoke();
}
}
Who is going to crap himself? :)
A parent class is constructed from outside the child class, thus, it's constructor cannot be called from inside the child. How should one go about accessing properties of the parent from the child in this case.
Example:
class MyParent {
protected $args;
protected $child;
public function MyParent($args=false){
$this->args=$args;
$this->child=new MyChild();
}
public function main(){
$this->child->printArgs();
}
}
class MyChild extends MyParent{
public function MyChild(){}
public function printArgs(){
Echo "args: ".$this->args['key']." = ".$this->args['value']."\n";
}
}
$parent=new MyParent(array('key'=>'value'));
$parent->main();
Empty variables are returned when run:
jgalley#jgalley-debian:~/code/otest$ php run.php
args: =
__construct() is the constructor. You are using a variant from ancient PHP4-times.
You instanciate two completely different objects, therefore of course the property $args is completely independent.
abstract class MyParent {
protected $args;
public function __construct($args=false){
$this->args=$args;
}
public function main(){
$this->printArgs();
}
abstract public function printArgs();
}
class MyChild extends MyParent{
public function printArgs(){
Echo "args: ".$this->args['key']." = ".$this->args['value']."\n";
}
}
$$object=new MyChild(array('key'=>'value'));
$object->main();
This at least works, but a problem is, that I don't know exactly what are the design goals. Because it seems to be a kind of cli-Application you should have a look at existing solutions to get an idea, how it could get solved.
I have a strange issue where I set values in a parent class but cannot access those values in a child class extending the parent.
class Parent
{
protected $config;
public function load($app)
{
$this->_config();
$this->_load($app);
}
private function _config()
{
$this->config = $config; //this holds the config values
}
private function _load($app)
{
$app = new $app();
$this->index;
}
}
class Child extends Parent
{
public function index()
{
print_r($this->config); // returns an empty array
}
}
$test = new Parent();
$test->load('app');
when I do that i get an empty array printed out. But if I do this then I am able to access those config values.
private function _load($app)
{
$app = new $app();
$app->config = $this->config
$app->index;
}
and
class Child extends Parent
{
public $config;
....
}
then I can access the config data from the parent.
You are accessing the values before anything is initialized there. First you have to set the values.
Example: call a method is the parent class, which set the value, on the contructor of the child class.
class Child extends Parent
{
public function __construct() {
$this -> setConfig(); //call some parent method to set the config first
}
public function index()
{
print_r($this->config); // returns an empty array
}
}
Update: You also seem to confused about concept of OOP
class Parent { ..... }
class child extends Parent { ..... }
$p = new Parent(); // will contain all method and properties of parent class only
$c = new Child(); // will contain all method and properties of child class and parent class
But, you have to work with parent methods and properties just the same way you would do in the normal object.
Lets See another example:
class Parent {
protected $config = "config";
}
class Child extends Parent {
public function index() {
echo $this -> config; // THis will successfully echo "config" from the parent class
}
}
But another example
class Parent {
protected $config;
}
class Child extends Parent {
public function index() {
echo $this -> config; //It call upon the parent's $config, but so far there has been no attempt to set an values on it, so it will give empty output.
}
}
It's because the property in the parent is protected. Set it to public and you can access it in child classes. Or alternatively, create a method in the parent class which returns the config:
public function getConfig()
{
return $this->config;
}
See the following example (PHP)
class Parent
{
protected $_property;
protected $_anotherP;
public function __construct($var)
{
$this->_property = $var;
$this->someMethod(); #Sets $_anotherP
}
protected function someMethod()
...
}
class Child extends Parent
{
protected $parent;
public function __construct($parent)
{
$this->parent = $parent;
}
private function myMethod()
{
return $this->parent->_anotherP; #Note this line
}
}
I am new to OOP and am a bit ignorant.
Here to access the parents property I am using an instance of that class, which seems wrong :S (no need of being i child then). Is there an easy way, so that i can sync the parent properties with the child properties and can directly access $this->anotherP without having to use $this->parent->anotherP ?
As your Child class is extending your Parent class, every properties and methods that are either public or protected in the Parent class will be seen by the Child class as if they were defined in the Child class -- and the other way arround.
When the Child class extends the Parent class, it can be seen as "Child is a Parent" -- which means the Child has the properties of the Parent, unless it redefines those another way.
(BTW, note that "parent" is a reserved keyword, in PHP -- which means you can't name a class with that name)
Here's a quick example of a "parent" class :
class MyParent {
protected $data;
public function __construct() {
$this->someMethodInTheParentClass();
}
protected function someMethodInTheParentClass() {
$this->data = 123456;
}
}
And it's "child" class :
class Child extends MyParent {
public function __construct() {
parent::__construct();
}
public function getData() {
return $this->data; // will return the $data property
// that's defined in the MyParent class
}
}
That can be used this way :
$a = new Child();
var_dump($a->getData());
And you'll get as output :
int 123456
Which means the $data property, defined in the MyParent class, and initialized in a method of that same MyParent class, is accessible by the Child class as if it were its own.
To make things simple : as the Child "is a" MyParent, it doesn't need to keep a pointer to... itself ;-)
This may save you a few hours of searching around.
Remember: Your Child class only inherits the properties DEFINED in the Parent class... So if you instantiate an object using Parent class and then populate it with data, then this data will NOT be available in your child class...
It's super obvious of course, but I'm guessing others may run into the same issue.
A super simple solution is not to extend anything, simply pass the $object of your parent class into your child class through a constructor. This way you have access to all the properties and methods of the object generated by parent class
Example
class child {
public parentObject;
public function __construct($parentObject) {
$this->parentObject = $parentObject;
}
}
If your $parentObject has a public property $name, then you can access it inside the child class with a function like:
public function print_name() {
echo $this->parentObject->name;
}