Lets say I have a class that is responsible for composing another class:
class ClassBuilder
{
protected $baseClass;
public function __construct()
{
$this->baseClass = new BaseClass();
}
public function set()
{
$this->baseClass->foo = 'bar';
}
// other methods to further modify BaseClass
}
class BaseClass
{
public $foo;
}
class ChildClass extends BaseClass {}
I want to create a method in the ClassBuilder that would allow me to update its baseClass property to an instance of ChildClass with the same property values as the current BaseClass object. How can I do that?
public function update()
{
// $this->baseClass = new ChildClass() with the current property values in BaseClass
}
I'm not sure that your overall approach is correct, but about the only way is to loop and set:
public function update()
{
$new = new ChildClass();
foreach($this->baseClass as $name => $value) {
$new->$name = $value;
}
$this->baseClass = $new;
//or
$this->baseClass = clone $new;
}
<?php
abstract class A {
public static $var = "A";
public function setVar() {
}
public function test() {
$this->setVar();
echo static::$var;
}
public function returnVar() {
return static::$var;
}
}
class B extends A {
public function setVar() {
static::$var = 'B';
}
}
class C extends A {
public function setVar() {
static::$var = 'C';
}
}
$class = new B();
$class->test();
$class2 = new C();
$class2->test();
echo "</br>";
echo $class->returnVar();
echo $class2->returnVar();
?>
What I'm trying to do is make the variable $var static to the class that extends abstract class A without having to re-declare it else where.
So say perhaps I create multiple objects from class B that extends A, I want all objects made from class B to share the same $var value.
Say I then create objects based on class C, they should all share the same value of $var...
This is the result I'm currently getting:
BC
CC
However, what I'm looking for is:
BC
BC
Thanks
Try it like that:
#setting
public function setVar() {
static::$var[get_class($this)] = 'B';
}
#getting in abstract
public function returnVar() {
return static::$var[get_class($this)];
}
#add this in the abstract class
public function setVar();
class A {
private $aa;
protected $bb = 'parent bb';
function __construct($arg) {
//do something..
}
private function parentmethod($arg2) {
//do something..
}
}
class B extends A {
function __construct($arg) {
parent::__construct($arg);
}
function childfunction() {
echo parent::$bb; //Fatal error: Undefined class constant 'bb'
}
}
$test = new B($some);
$test->childfunction();
Question:
How do I display parent variable in child?
expected result will echo 'parent bb'
echo $this->bb;
The variable is inherited and is not private, so it is a part of the current object.
Here is additional information in response to your request for more information about using parent:::
Use parent:: when you want add extra functionality to a method from the parent class. For example, imagine an Airplane class:
class Airplane {
private $pilot;
public function __construct( $pilot ) {
$this->pilot = $pilot;
}
}
Now suppose we want to create a new type of Airplane that also has a navigator. You can extend the __construct() method to add the new functionality, but still make use of the functionality offered by the parent:
class Bomber extends Airplane {
private $navigator;
public function __construct( $pilot, $navigator ) {
$this->navigator = $navigator;
parent::__construct( $pilot ); // Assigns $pilot to $this->pilot
}
}
In this way, you can follow the DRY principle of development but still provide all of the functionality you desire.
Just echo it since it's inherited
echo $this->bb;
With parent::$bb; you try to retrieve the static constant defined with the value of $bb.
Instead, do:
echo $this->bb;
Note: you don't need to call parent::_construct if B is the only class that calls it. Simply don't declare __construct in B class.
class A {
private $aa;
protected $bb = 'parent bb';
function __construct($arg) {
//do something..
}
private function parentmethod($arg2) {
//do something..
}
}
class B extends A {
function __construct($arg) {
parent::__construct($arg);
}
function childfunction() {
echo parent::$this->bb; //works by M
}
}
$test = new B($some);
$test->childfunction();`
$bb has now become the member of class B after extending class A.
So you access $bb like it's an attribute of class B.
class A {
private $aa;
protected $bb = 'parent bb';
function __construct($arg) {
//do something..
}
private function parentmethod($arg2) {
//do something..
}
}
class B extends A {
function __construct($arg) {
parent::__construct($arg);
}
function childfunction() {
echo $this->bb;
}
}
$test = new B($some);
$test->childfunction();
all the properties and methods of the parent class is inherited in the child class so theoretically you can access them in the child class but beware using the protected keyword in your class because it throws a fatal error when used in the child class.
as mentioned in php.net
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.
PHP Accessing Parent Class Protected Variable & Methods
class A {
protected $bb = 'parent bb';
protected function sayHello(){
echo 'Say Hello';
}
}
class B extends A {
public function childfunction() {
echo $this->bb.'<br>';
echo $this->sayHello();
}
}
$test = new B();
$test->childfunction();
Through parent class contructor you can pass data to parent class from child class. Have a look below example for better understanding
<?php
class Student
{
public $name;
function __construct($name){
$this->name = $name;
}
}
class Test extends Student
{
public $age;
function __construct($name,$age){
$this->age = $age;
parent::__construct($name);
}
}
$obj = new Test("sajib khan" ,21);
echo $obj->name;
echo $obj->age;
?>
class A {
private $points = 100;
public function getPoints() {
return $this->points;
}
}
class B extends A {
protected $points = 70;
public function getPoints() {
return parent::getPoints();
}
}
$element = new B();
echo $element->getPoints();
change the visibility private or protected for test
I have code similar to the following:
class ModuleRaceRegistration extends Module
{
protected $strTemplate = "template";
protected function compile()
{
// this doesn't work
$this->strTemplate = "template2";
}
}
From within the compile function I need to change the $strTemplate member. How can I do this?
Is an error being returned? Also, this might not be the case but compile is a protected method so you can only call it from within the class. If you are trying to call it from outside of the class, then it would need to be public.
Let me try
Example from manual
<?php
abstract class Base {
abstract protected function _test();
}
class Bar extends Base {
protected function _test() { }
public function TestFoo() {
$c = new Foo();
$c->_test();
}
}
class Foo extends Base {
protected function _test() {
echo 'Foo';
}
}
$bar = new Bar();
$bar->TestFoo(); // result: Foo
?>
Suppose we have a class. We create an object from the class and when we do the class Extends himself base on the object initialization value..
For example:
$objectType1 = new Types(1);
$objectType1->Activate(); // It calls an activation function for type 1
$objectType2 = new Types(2);
$objectType2->Activate(); // It calls an activation function for type 2
I don't want to use the standard procedure of class extending:
class type1 extends types{}
You cannot extend a class at runtime. Use an instance variable to distinct the two type or use a factory.
Example for instance variable:
class Types() {
private $type;
public function __construct($type) {
$this->type = $type;
}
public function activate() {
if($this->$type == 1) {
// do this
}
else if($this->type == 2) {
// do that
}
}
}
Example for factory pattern:
abstract class BaseClass {
// Force Extending class to define this method
abstract public function activate();
// Common method
public function printOut() {
echo "Hello World";
}
}
class Type1 extends BaseClass {
public function activate() {
// do something
}
}
class Type2 extends BaseClass {
public function activate() {
// do something else
}
}
class TypeFactory {
public static function getType($tpye) {
if($type == 1) {
return new Type1();
}
else if($type == 2) {
return new Type2();
}
}
}
then you do:
$obj = TypeFactory::getType($1);
$obj->activate();
Update:
Since PHP 5.3 you can use anonymous functions. Maybe you can make use of this.