Multi level inheritance in PHP - php

I'm trying to access and modify data that is in a parent class which is a child of another class.
I've a parent class
class GrandParent {
protected $data = 1;
public function __construct() {}
public function getData() {
return $this->data;
}
}
Below is my first level child
class Child extends GrandParent {
protected $c1Data;
public function __construct() {
$this->c1Data = parent::getData();
$this->c1Data = 2;
}
public function getData() {
return $this->c1Data;
}
}
If I try to instantiate the Child class and do getData(), I get 2 which is normal. I've another class that inherits Child.
class GrandChild extends Child {
protected $c2Data;
public function __construct() {
$this->c2Data = parent::getData();
}
public function getData() {
return $this->c2Data;
}
}
The problem is that if I try to instantiate GrandChild I and get the data I'm getting null. Is it possible to make my GrandChild class inherit $c1Data = 2 and work with it. I want also to be able to use the Child and GrandParent classes on their own and not be abstract.

You're getting NULL because __constructor of a Child class is not invoked and that's why c1Data property is NOT SET. You should explicitly call for Child __constructor:
class GrandChild extends Child {
protected $c2Data;
public function __construct() {
// here
parent::__construct();
$this->c2Data = parent::getData();
}
public function getData() {
return $this->c2Data;
}
}

This is how you add two integers and display the result with Multi
Level Inheritance in PHP.
<?php
/*
Inheritance:
multiple classes
Parent class/child class
senior and junior
child class extends some data or functions of parent class
child class has its own functions
child class can access all public and protected data and functions
*/
//Multi Level Inheritance Every class extends other class
//Parent Class
class A{
//data
var $a;
function setA()
{
$this->a=10;
}
}
//child class
class B extends A{
var $b;
function setB()
{
$this->b=20;
}
}
class Addition extends B{
function add()
{
$this->setA();
$this->setB();
return $this->a+$this->b;
}
}
class Print1 extends Addition{
function print()
{
$this->add();
print("a=".$this->a);
print("<br/>b=".$this->b);
print("<br/>Addtion:".$this->add());
}
}
//make object
$obj1=new Print1();
$obj1->print();
/*
Make Subtraction, multiplication and division classes and print the values as
a=10
b=20
Addtion=30
Subtraction=-10
Multiplication=200
Division:0.5
*/
?>

Related

Extends a PHP class and it's children

In one of my projects, I use an external library providing two classes : DrawingImage and DrawingCharset, both of them extending BaseDrawing.
I want to extends BaseDrawing to add some properties and alter an existsing method. But I also want theses modifications in "copy" of existing children (DrawingImage and DrawingCharset).
There is a simple way to do it ? Extending don't seems to be a solution : I must duplicate code between each subclass. And I'm not sure i can call a parent method through Trait.
Traits can access properties and methods of superclasses just like the subclasses that import them, so you can definitely add new functionality across children of BaseDrawing with traits.
<?php
class BaseDrawing
{
public $baseProp;
public function __construct($baseProp)
{
$this->baseProp = $baseProp;
}
public function doSomething()
{
echo 'BaseDrawing: '.$this->baseProp.PHP_EOL;
}
}
class DrawingImage extends BaseDrawing
{
public $drawingProp;
public function __construct($baseProp, $drawingProp)
{
parent::__construct($baseProp);
$this->drawingProp = $drawingProp;
}
public function doSomething()
{
echo 'DrawingImage: '.$this->baseProp.' - '.$this->drawingProp.PHP_EOL;
}
}
class DrawingCharset extends BaseDrawing
{
public $charsetProp;
public function __construct($baseProp, $charsetProp)
{
parent::__construct($baseProp);
$this->charsetProp = $charsetProp;
}
public function doSomething()
{
echo 'DrawingCharset: '.$this->baseProp.' - '.$this->charsetProp.PHP_EOL;
}
}
/**
* Trait BaseDrawingEnhancements
* Adds new functionality to BaseDrawing classes
*/
trait BaseDrawingEnhancements
{
public $traitProp;
public function setTraitProp($traitProp)
{
$this->traitProp = $traitProp;
}
public function doNewThing()
{
echo 'BaseDrawingEnhancements: '.$this->baseProp.' - '.$this->traitProp.PHP_EOL;
}
}
class MyDrawingImageImpl extends DrawingImage
{
// Add the trait to our subclass
use BaseDrawingEnhancements;
}
class MyDrawingCharsetImpl extends DrawingCharset
{
// Add the trait to our subclass
use BaseDrawingEnhancements;
}
$myDrawingImageImpl = new MyDrawingImageImpl('Foo', 'Bar');
$myDrawingImageImpl->setTraitProp('Wombats');
$myDrawingCharsetImpl = new MyDrawingCharsetImpl('Bob', 'Alice');
$myDrawingCharsetImpl->setTraitProp('Koalas');
$myDrawingImageImpl->doSomething();
$myDrawingCharsetImpl->doSomething();
$myDrawingImageImpl->doNewThing();
$myDrawingCharsetImpl->doNewThing();

Way to get the output of an abstract function

I have an abstract class with an abstract method 'run'. Child classes extending this implements run and returns a bool as output.
Is there a way that I can get the status of run (true/false) method in the abstract class.
I want this as I am trying to add few statistics as how many classes failed/passed to execute the run method. I already have many classes extending this and don't want to add anything into those and get these statistics for free.
abstract class parent {
// I need the status of the run method in here
public abstract function run();
}
class child extends parent {
public function run() {
if (implementation) {
return true;
} else {
return false;
}
}
}
Help appreciated.
Define a non-abstract method in the parent that calls the abstract method and gets the result.
abstract class parent {
private $run_result;
public function run() {
$this->run_result = $this->run_internal();
}
abstract protected function run_internal();
}
class child extends parent {
protected function run_internal() {
if (implementation) {
return true;
} else {
return false;
}
}
}

PHP - Extends class modify protect parent

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

accessing parent property values in child class

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;
}

Separate static variable for every child

I want to do some cache in my ORM
class Base {
static public $v=array();
static public function createById($id){
if(!array_key_exists($id, static::$v)){
static::$v[$id] = new static; //Get from DB here. new static is just example
}
return static::$v[$id];
}
}
class User extends Base{
}
class Entity extends Base{
}
But now cache is merged
var_dump(User::createById(1));
var_dump(Entity::createById(1));
results
object(Model\User)#4 (0) {
}
object(model\User)#4 (0) {
}
If I made
class Entity extends Base{
static public $v=array();
}
class User extends Base{
static public $v=array();
}
I get what I need:
object(Model\User)#4 (0) {
}
object(model\Entity)#5 (0) {
}
Is it possible to do it without declaration in every class?
If its that important that you don't re-declare the property in each child class, the only solution I can think of is, which isn't exactly what you wanted, but it should get you the same functionality, is sharing the same property on the base class to store the cache for all the child classes, but using the child class name as a key in the cache array:
class Base {
public static $v=array();
public static function createById($id){
$called = get_called_class();
if (!isset(self::$v[$called])) {
self::$v[$called] = array();
}
$class_cache = &self::$v[$called];
if(!array_key_exists($id, $class_cache)){
$class_cache[$id] = new static;
}
return $class_cache[$id];
}
}
Yes, its not pretty... but AFAIK, what you asked for isn't possible.

Categories