Reputation: 311
class parents{
public $a;
function __construct(){
echo $this->a;
}
}
class child extends parents{
function __construct(){
$this->a = 1;
parent::__construct();
}
}
$new = new child();//print 1
This code above print 1,which means whenever we create an instance of a child class,and assign value to properties inherited from its parent,the property in its parent class also has been assigned.But the code below shows different:
class parents{
public $a;
function test(){
$child = new child();
echo $this->a;
}
}
class child extends parents{
function __construct(){
$this->a = 1;
}
}
$new = new parents();
$new->test();//print nothing
Where I assign value to its child class and the parent apprently didn't have the value it assigned to its child class,why?
Thanks!
Upvotes: 0
Views: 3004
Reputation: 24645
You are mixing object composition and class inheritance.
Inheritance (realized through the extends keyword) defines an is a
relationship.
Composition defines a has a
relationship.
To illustrate this concept we will start with inheritance.
class Person {
public $name;
public function talk(){};
public function poop(){};
}
class Parent extends Person {
public function __construct($name) {
$this->name = $name;
}
}
class Child extends Person {
public function __construct($name){
$this->name = $name;
}
}
In this example we are defining a class
of things called People. From that definition we are deriving two different subtypes of People, Parent and Child. When we subtype a class then the subtype gains it's own copy of all of the properties and has access to all of the methods defined in the base type, so without defining it a Child and Parent have a name and can both talk and poop by virtue of also being a person.
For example:
$parent = new Parent("Homer");
$child = new Child("Bart");
$parent->talk();
$child->poop();
Composition is used when you want to implement a has a relation ship. Lets revise our type definition of Parent.
class Parent extends Person {
public $children = array();
public function __construct($name) {
$this->name = $name;
}
public function addChild(Child $child){
$this->children[] = $child;
}
}
What we have now allowing if for a Parent to have a
child.
$parent = new Parent("Homer");
$child = new Child("Bart");
$parent->addChild($child);
// now I can access homers first child
echo $parent->children[0]->name;
Upvotes: 1
Reputation: 4161
It's because in the first example you instantiate child
$new = new child();//print 1
and in the second you instantiate parents
$new = new parents();
The second works the same as the first using $new = new child();
If you want to access $a by instantiating child() you need to do it like this:
class parents{
public $a;
function test(){
$child = new child(); //CHANGE HERE
echo $child->a;
}
}
class child extends parents{
function __construct(){
$this->a = 1;
}
}
$new = new parents();
$new->test();
Upvotes: 0
Reputation: 4072
In the top example, since the construct function is being called from the child class, it is treating the object being used as if it were the child object that is just using a function in the parent class as if it were it's own.
In the bottom example you have two separate objects acting independently. The parent object has it's $a and so does the child, but they are not the same $a since they are contained in separate objects. so when you print $this->a in the parent class, it is referring to the parent's instance of $a whereas if you echo $a after setting $this->a =1 in the child class it would display the child's instance of $a.
Hope this cleared some stuff up for you.
Upvotes: 1
Reputation: 15629
That happens, because you have two different instances, which have nothing in common(except the the inheritance..) The behavior you except could be generated with inner classes - which php don't support.
If you want to share an var accros every instance, you have to make it static
class parents{
public static $a;
function test(){
$child = new child();
echo self::$a;
}
}
class child extends parents{
function __construct(){
self::$a = 1;
}
}
$new = new parents();
$new->test();
which isn't probably what you want. Or you tell exactly, where you want to change your var
class parents{
public $a;
function test(){
$child = new child();
echo $child->a;
}
}
class child extends parents{
function __construct(){
$this->a = 1;
}
}
$new = new parents();
$new->test();
Upvotes: 0
Reputation: 356
When you instantiate parent
, the instance of child
created extends the parent
class with to test()
function. However, that doesn't change the value of $a
.
Upvotes: 0