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;
}
Related
I have a parent class I'll be calling 'ParentClass' and a child class (that extends from it) which I'll be calling 'ChildClass'.
ParentClass has protected properties $prop1 and $prop2 which I want ChildClass to access. But I'm getting NULL from them.
ParentClass has a __construct() method which sets the properties received through dependency injection.
ParentClass instantiates ChildClass from one of its methods.
ChildClass overwrites the parent constructor, but doesn't contain any code inside of its own __construct() method.
I have already tested the properties at the parent class with var_dump($this->prop1). It returns the value I'm expecting.
However, if I var_dump($this->prop1) from the child class, I get NULL.
class ParentClass {
protected $prop1;
protected $prop2;
public function __construct($prop1, $prop2) {
$this->prop1 = $prop1;
$this->prop2 = $prop2;
}
public function fakeMethod() {
$child = new ChildClass;
$child->anotherFakeMethod();
// logic
}
}
class ChildClass extends ParentClass {
public function __construct() {
// this overrides the parent constructor
}
public function anotherFakeMethod() {
$prop1 = $this->prop1;
$prop2 = $this->prop2;
var_dump($this->prop1);
// returns NULL
}
}
Why can't the child class access the parent class' properties if it extends from it?
They are accessible, but they will be null because they are not passed to the parent constructor from the child:
(new ChildClass(1,2))->anotherFakeMethod();
Sandbox
Output
NULL
Your classes produce the expected result of null in this case. Well it produces what I would expect it to based on how it's coded.
To fix it, you must pass that data back to the parent class through the child's constructor, or remove the child's constructor. Like this:
class ChildClass extends ParentClass {
public function __construct($prop1, $prop2) {
parent::__construct($prop1, $prop2);
}
....
}
After the above change:
(new ChildClass(1,2))->anotherFakeMethod();
Output
int(1)
Sandbox
Which is what I would expect from this line as it's basically the first argument used in the constructor:
var_dump($this->prop1);
You can also do it this way, if you know what they are in the child class:
public function __construct() {
parent::__construct(1, 2); //say I know what these are for this child
}
You could of course set them manually in the new constructor but that would be WET (write everything twice) or unnecessary duplication, in this case.
Cheers!
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;
}
I've two classes in 2 files.
First (parent.php):
class Parent{
var $ParentVar;
}
Second (child.php):
class Child{
var $ChildVar = 'im a childvar';
}
How can I set $ChildVar value to $ParentVar for printing 'im a childvar' in Parent class?
Firstly, you need to use inheritance correctly, so:
class Child extends Parent {
Secondly, you should never be accessing the value of a Child from the parent. What you could do, is to define an abstract function in the Parent class which the Child needs to implement, and then code in the Parent could then call the Child's function. For example:
abstract class Parent {
abstract protected function returnSomeValue();
public function outputSomeValue() {
return $this->returnSomeValue();
}
}
class Child extends Parent {
protected $ChildVar = 'im a childvar';
protected function returnSomeValue() {
return $this->ChildVar;
}
}
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 mean something like that:
class parentClass {
public function method() {
echo $this->prop;
}
}
class childClass extends parentClass {
public $prop = 5;
}
How can I get a child prop from the parent prop?
Thanks...
Either I don't fully understand what you want or the solution is as trivial as the following code.
class parentClass {
public function method() {
echo $this->prop;
}
}
class childClass extends parentClass {
public $prop = 5;
}
$object = new childClass();
$object->method();
I mean the child class is extending the base class which means it will also inherit all the methods of its parent's class. That makes the whole process of using the parent's class method as simple as calling it from the instance of the child class.
All protected and public members of child classes are visible from within their parent class in PHP, so the example code you provided should work just fine. Quote from the php doc:
Members declared protected can be accessed only within the class
itself and by inherited and parent classes.
But the actual question is: do you really need it?
The proper OO way would be to define a self-contained parent class that expresses something. It should not need to access properties of child classes - this is a so-called code smell. If you really think that you have a case where a similar construct is necessary, you are probably looking for abstract methods, which guarantee that every child class has this property:
abstract class Animal {
public function makeNoise() {
echo $this->getNoiseString();
}
protected abstract function getNoiseString();
}
class Cat extends Animal {
protected function getNoiseString() {
return 'meow';
}
}
//parent
class parentClass {
protected $prop = null;
public function method() {
echo $this->prop;
}
}
//child
class childClass extends parentClass {
protected $prop = 5;
}
Make sure the variable is defined in the parentclass as well. So it will be accessible by the parent.