I know that protected attributes are available to subclasses when they are defined in a class, but are they available in parent classes? For example:
class My_Class {
// Is $name available here?
}
class My_Subclass extends My_Class {
protected $name = 'Henry';
}
Code which you write in the parent class can access that property if run in the context of a subclass. Made sense? Example:
class My_Class {
public function test() {
echo $this->name;
}
}
class My_Subclass extends My_Class {
protected $name = 'Henry';
}
$a = new My_Class;
$b = new My_Subclass;
$a->test(); // doesn't work
$b->test(); // works
Obviously (hopefully), instances of My_Class won't suddenly sprout a name property, so $a->test() won't work. Precisely because of that it's a very bad idea to make a class rely on properties which it doesn't define.
Visibility doesn't only relate to $this BTW, watch:
class My_Class {
public function test($obj) {
echo $obj->name;
}
}
class My_Subclass extends My_Class {
protected $name = 'Henry';
}
$a = new My_Class;
$a->test(new My_Subclass); // Amazeballs, it works!
A parent class has access to the property if and when it tries to access it. That doesn't mean all parent classes suddenly get a copy of that property themselves.
The parent class has no information about its subclasses, so no, $name is not available in My_Class.
Edit: As #deceze points out correctly in a comment code in My_Class can access $name, but that only works if the object was instantiated from a subclass implementing that variable. Accessing the variable in the parent class will give an Undefined Property notice.
Also I would consider that bad style and architecture, but that's my opinion ;)
Sometimes it 'can', but you really shouldn't do it
class A {
function set() {
$this->v = 'a';
}
function get() {
return $this->v;
}
}
class B extends A{
protected $v = 'b';
}
echo $b->get();//b
$b->set();
echo $b->get();//a
var_dump($b); //class B#1 (1) { protected $v => string(1) "a"}
$a = new A();
echo $a->get(); //Undefined property: A::$v
$a->set();
$a->get();//a
var_dump($a); //class A#2 (1) { public $v => string(1) "a"}
No. "protected" access modifier makes any property and method to be visible from the derived class. This is what it is used for. But parent class never knows any information about the derived class.
For more information please see this article.
Related
I searched everywhere but did not find any solution to this question.
Following is my code where I want to access the $myvar of the super class in the subclass but I don't know how? when I use $this keyword it accesses the variable in the same class but not the one in super class. please any help will be greatly appreciated.
<?php
class First{
protected $myvar = "First Class";
}
class Second extends First{
public $myvar = "Second Class";
function __construct(){
echo $this -> myvar;// here I want to access the $myvar of super class
}
}
$obj = new Second();
?>
Note: I can achieve the same functionality in java by using the super keyword.
You may create a custom function that returns the variables from the parent class BUT keep in mind that the variables should be "private":
class First{
private $myvar = "First Class";
protected function get_variable($var_name)
{
return $this->{$var_name};
}
}
class Second extends First{
public $myvar = "Second Class";
function __construct() {
echo parent::get_variable('myvar');
}
}
$obj = new Second();
The way you try to do this will not work, as Rizier mentioned. Maybe static properties can be useful to you (depending on your needs ofcourse)
<?php
class a {
protected static $var = 'a';
}
class b extends a {
protected static $var = 'b';
public function __construct() {
echo self::$var;
echo parent::$var;
}
}
$b = new b();
You could also reconstruct a in b. You'd be able to leverage the inheritance for methods and maybe other properties, while being able to use the default value in a-constructor.
<?php
class a {
protected $var = 'a';
}
class b extends a {
protected $var = 'b';
public function __construct() {
echo $this->var;
$a = new a();
echo $a->var;
}
}
$b = new b();
The main question I think you should answer is why you want a class to inherit from another but still want to be able to change/modify stuff in the parent. That's kinda counterproductive for the whole inheritance design.
You can't you are overwritten in when creating the sub class which inherits from the parent class. So you would have to change the name for it.
You override the parent parameter with:
public $myvar = "Second Class";
Remove this line to use the inherits from parent class or change the name of the child class parameter.
class A {
protected $a;
// SOME CODE
}
class B extends A {
// SOME CODE
}
How can i edit the protected value of the variable $a inside the B class ?
I'm trying to use parent::$a = "Some Value" but doesn't work.
protected instance properties, those which where not declared using static, can be accessed in subclasses using $this :
class A {
protected $a;
// SOME CODE
}
class B extends A {
// SOME CODE
public function edit($val) {
$this->$a = $val;
echo "a is now {$this->a}\n";
}
}
call:
$b = new B();
$b->edit('foo'); // a is now foo
Refer to the manual, especially the examples.
class B extends A {
public function foo($val)
{
$this->a = $val;
}
}
quite simple :)
Remember that
Members declared protected can be accessed only within the class
itself and by inherited and parent classes
from php manual
i have two classes one parent and the other extends , I need to use main vars in extended class.
for example
class parentClass
{
$this->value = null
function __construct()
{
echo "im parent" ;
}
}
class childClass extends parentClass
{
function sayIt()
{
var_dump($this->value);
}
}
$p = new parentClass ;
$p->value = 500 ;
$c = new childClass ;
$c->sayIt(); // this output null ! i want it to output 500 , how i can do that
thanks
that's not the way inheritance works. The childClass is not automatically connected to the parent class, it just inherits from the parentClass it just inherits all public and protected variables/methods from teh parent. It is not connected to the parent's instances.
if you wnat it to output 500 you have to assign it to the child class instance somehow:
$c = new childClass ;
$c->value = 500;
$c->sayIt()
If you need a variable shared between all classes and instances you can use a static variable.
Bad Bad Bad The code is strictly for educational purpose i would advice you to get a book on basic Principles of Object Oriented programming
Making your variable static would make it accessible via the child class
class parentClass {
public static $value = null;
function __construct() {
echo "patent called";
}
}
class childClass extends parentClass {
function sayIt() {
var_dump(self::$value);
}
}
$p = new parentClass();
parentClass::$value = 500;
$c = new childClass();
$c->sayIt();
you are confusing with class constructs and references.
$p is an instance of the parentclass.
$c is an instance of the childclass.
they don't share their data.
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.
I'm a little confused about this paragraph on OO visibilty in PHP. was curious if someone could explain it to me. examples would be GREAT! my brain is not thinking clear.
http://www.php.net/manual/en/language.oop5.visibility.php
The first paragraph reads
The visibility of a property or method
can be defined by prefixing the
declaration with the keywords public,
protected or private. Class members
declared public can be accessed
everywhere. Members declared protected
can be accessed only within the class
itself and by inherited and parent
classes. Members declared as private
may only be accessed by the class that
defines the member.
how can a parent class access a childs class member?
That's how:
class A {
public function test() {
$b = new B;
echo $b->foo;
}
}
class B extends A {
protected $foo = 'bar';
}
$a = new A;
$a->test();
PHP is an interpreted language. Properties are resolved at runtime, not at the compiling stage. And access modifiers are just checked when a property is accessed.
It makes no difference if you ad-hoc inject a new (undeclared) property so it becomes public, or if you declare a protected property in an inherited class.
The private really only affects the accessibility from the outside. The ->name resolving at runtime works regardless of that. And the PHP runtime simply doesn't prope if the property declaration was made for the current object instances class. (Unlike for private declarations.)
public scope: property (method, variable etc) can be accessed from any class in any file.
class Example {
public $foo;
}
$example = new Example;
$example->foo = 3; // everything OK
private scope: property can only be accessed only by same class.
class Example {
private $foo;
}
class Child_Class extends Example {
public function some_method()
{
parent::foo = 3; // raises error
}
}
protected scope: property can only be accessed by same class or by other classes that extend it.
class Example {
protected $foo;
}
class Child_Class extends Example {
public function some_method()
{
parent::foo = 3; // this is OK
}
}
It all has to do with a technique named encapsulation, in which you must not allow a class member's state or behavior to be changed outside the class. http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
Protected is a type of visibility which makes properties and methods declared protected available in the child classes of the declared class.
class Parent {
public $name = 'MyName';
protected $age = 20;
private $school = 'MySchool';
}
class Child extends Parent {
public function __construct() {
echo $this -> name; // valid as public
echo $this -> age; // valid as protected
echo $this -> school; // invalid as private
}
}
There you understand protected is something that used in inheritance.