12/07/2015

PHP Objects: How to construct a Child & Parent class & pass variables

PHP has had object-oriented capabilities for a few years. One aspect of this programming methodology is to create "child" classes from "parent" classes. Ex. A "Dog" class would be a child extension of a parent "Animal" class. All animals in the parent class are either alive or dead and have a weight. All dogs will have have weight and living status, but also potentially have 4 legs and ear flaps. A "Bird" class would also have weight and a living status because it is also an extension of the parent "Animal" class, but instead would only have 2 legs and wings. Birds don't have ear flaps; dogs don't have wings.

Also, the values stored within an object can have the following statuses:

  • private
  • protected
  • public.


Okay, you knew that, right.

So, what happens if your parent Animal class requires that some kind of parameter be sent to it -- either a value or another object. Here, I'll show you what can happen if the parent properties have private status.

GOAL: I want to get a URL for a website that lets me search for dogs by certain characteristics.
  • I'm going to create a new dog.
  • Then I'm going to ask for a search URL based on that dog's weight.

THERE IS AN ERROR THAT OCCURS.

I am expecting to get back a URL that reads:
  http://www.someAwesomeUrl.com/search.php?weight=10

But instead, I get this error message:
  Fatal error: Call to a member function getWebUrl() on a non-object

The problem lies within the definition of the parent class "Animal". Notice that the "Animal" class' $setup variable is set to "private".  This is preventing me from running the function in the parent "Animal" properly. As far as the parent is concerned, the $setup object was never instantiated, so there is no method called getWebUrl() to access.

Huh? But, we sent the $setup object through the child "Dog" object, right? Well, we did. But the parent "Animal" ignored that setting because of the "private" status on the "Animal" version of the $setup object.

We can fix this error in one of two ways:
  1. Change the parent object "Animal" to have a "protected" setting on the $setup object instead of "private."
  2.  Add a line of code to instantiate the parent object and passes the parameters to it.
The second way uses a line of code that will look something like this:

     parent::__construct($parameter1,$parameter2,$parameter3);

So, in this specific case, I'm going to change the Dog class by adding this line :

    parent::__construct($setup);


-- VERSION OF CODE WITH ERROR --


// =========== MAIN PROGRAM ===========

// THESE ARE THE ONLY LINES OF CODE THAT RUN THIS PROGRAM
$setup = new Setup;

// PASSING THE NEW $setup OBJECT TO THE NEW $dog FOR INITIALIZATION
// ALONG WITH livingStatus, weight, earFloppiness, numberOfLegs
$dog = new Dog($setup,"alive",10,"very floppy",3);

// OUTPUT THE REQUESTED URL - A SEARCH BASED ON THE DOG'S WEIGHT
echo $dog->getSearchWeightLink();

// END OF PROGRAM
exit;

// =========== CLASSES ============

// THIS CLASS Setup IS USED TO PROVIDE
// VALUES USED ACROSS THE SITE
class Setup {
  private $webUrl;

  function __construct() {
     $this->webUrl = "http://www.someAwesomeUrl.com/";
  }

  function getWebUrl() {
    return $this->webUrl;
  }

}

// THIS CLASS Animal IS USED TO CREATE BASIC ATTRIBUTES
// AND METHODS THAT ARE COMMON TO ALL ANIMALS
class Animal {

  protected $weight;
  protected $livingStatus;
  private $setup;

  // INITIALIZING CONSTRUCTOR FOR THE OBJECT
  function __construct($setupObj) {
     $this->setup = $setupObj;
  }

  // FUNCTION RETURNS A WEB URL THAT WILL SEARCH
  // BY THE WEIGHT THAT WAS SENT
  function getSearchWeightLink() {
    $searchLink = $this->setup->getWebUrl() . "search.php?weight=" . $this->weight;
    return $searchLink;
  }
}

// THIS CLASS Dog IS USED TO CREATE ATTRIBUTES THAT ARE
// SPECIFIC ONLY TO DOGS
class Dog extends Animal {
  protected $earFloppiness;
  protected $numberOfLegs;

  // INITIALIZING CONSTRUCTOR FOR THE OBJECT
  function __construct($setupObj, $livingStatus, $weight, $earFloppiness, $numberOfLegs) {
     $this->setup = $setupObj;
     $this->livingStatus = $livingStatus;
     $this->weight = $weight;
     $this->earFloppiness = $earFloppiness;
     $this->numberOfLegs = $numberOfLegs;
  }
  // END Dog CLASS
}


-- CORRECTED VERSION OF THE Dog CLASS --


// THIS CLASS Dog IS USED TO CREATE ATTRIBUTES THAT ARE
// SPECIFIC ONLY TO DOGS
class Dog extends Animal {
  protected $earFloppiness;
  protected $numberOfLegs;

  // INITIALIZING CONSTRUCTOR FOR THE OBJECT
  function __construct($setupObj, $livingStatus, $weight, $earFloppiness, $numberOfLegs) {
     $this->setup = $setupObj;
     parent::__construct($setupObj);
     $this->livingStatus = $livingStatus;
     $this->weight = $weight;
     $this->earFloppiness = $earFloppiness;
     $this->numberOfLegs = $numberOfLegs;
  }
  // END Dog CLASS

No comments :

Post a Comment