hyperic
+ Reply to Thread
Results 1 to 2 of 2

Thread: OOP in PHP Part Two: Con/Destructors and Encapsulation

  1. #1
    Join Date
    Sep 2006
    Posts
    1,649

    OOP in PHP Part Two: Con/Destructors and Encapsulation

    If you haven't read the first part of my tutorial, do so now.

    Now we will get into two new ideas that come with classes. They are called constructors and destructors. Let's refer back to our Cheese class.

    [PHP]class Cheese {
    var $type;
    var $flavor;
    var $color;

    function giveDetails ($thetype, $theflavor, $thecolor) {
    $this->type = $thetype;
    $this->flavor = $theflavor;
    $this->color = $thecolor;
    }

    function showType() {
    return $this->type;
    }
    function showColor() {
    return $this->color;
    }
    function showFlavor() {
    return $this->flavor;
    }
    }[/PHP]

    In order to assign Cheese the properties of type, flavor, and color, we would have to call the giveDetails() function after declaring the new Cheese object. But what if we could do this all in one step? Here is the value of a constructor.

    [PHP] function __construct($atype, $aflavor, $acolor) {
    $this->type = $atype;
    $this->flavor = $aflavor;
    $this->color = $acolor;
    }[/PHP]

    You initialize a constructor by making a function named '__construct'. It doesn't have to take arguments; it could just echo a statement like "Object created successfully!". But in this case, we want it to take arguments. Let's see it in action.

    [PHP]<?php

    class Cheese {
    var $type;
    var $flavor;
    var $color;

    function __construct($atype, $aflavor, $acolor) {
    $this->type = $atype;
    $this->flavor = $aflavor;
    $this->color = $acolor;
    }

    function giveDetails ($thetype, $theflavor, $thecolor) {
    $this->type = $thetype;
    $this->flavor = $theflavor;
    $this->color = $thecolor;
    }

    function showType() {
    return $this->type;
    }
    function showColor() {
    return $this->color;
    }
    function showFlavor() {
    return $this->flavor;
    }
    }

    class MoreCheese extends Cheese {
    var $cost;

    function giveCost($f) {
    $this->cost = $f;
    }

    function showCost() {
    return $this->cost;
    }
    }

    $zargento = new Cheese("Cheddar", "Good", "Yellow");
    echo $zargento->showType();
    echo "<br>";
    echo $zargento->showFlavor();
    echo "<br>";
    echo $zargento->showColor();

    ?>[/PHP]

    Output:
    Code:
    Cheddar
    Good
    Yellow
    We entered the flavor, color, and type in one step, and it worked successfully. We can still use the giveDetails function later in the script if we want to change the properties of the Cheese object. Before we move on, I want to cover an aspect of older PHP versions. When wanting to use a constructor with PHP versions lower than PHP5, you must name the constructor the same name as you named the class. So for our Cheese class, instead of using __construct, you would use:

    [PHP] function Cheese($atype, $aflavor, $acolor) {
    $this->type = $atype;
    $this->flavor = $aflavor;
    $this->color = $acolor;
    }[/PHP]

    Now then, let's move on to destructors. These are called when you are finished with your object. It is useful in situations where you want to take certain actions just before the object is finished with. Suppose you have a script that is supposed to run for 20 seconds then display a message just before terminating. Someone takes that script and changes the run time to 50 seconds. Your script will display your 'termination' message after 20 seconds but the script will keep going. But by using a destructor, you are sure that this message will be displayed only when the object in question has truly served it's purpose. Here is what a destructor looks like.

    [PHP] function __destruct() {
    echo "Cheese has been eaten";
    }[/PHP]

    It looks just like the constructor, except the keyword destruct is used. A destructor usually won't take any arguments. Let's see it in action.

    [PHP]<?php

    class Cheese {
    var $type;
    var $flavor;
    var $color;

    function __construct ($atype, $aflavor, $acolor) {
    $this->type = $atype;
    $this->flavor = $aflavor;
    $this->color = $acolor;
    }

    function giveDetails ($thetype, $theflavor, $thecolor) {
    $this->type = $thetype;
    $this->flavor = $theflavor;
    $this->color = $thecolor;
    }

    function showType() {
    return $this->type;
    }
    function showColor() {
    return $this->color;
    }
    function showFlavor() {
    return $this->flavor;
    }

    function __destruct() {
    echo "Cheese has been eaten";
    }
    }

    class MoreCheese extends Cheese {
    var $cost;

    function giveCost($f) {
    $this->cost = $f;
    }

    function showCost() {
    return $this->cost;
    }
    }

    $zargento = new Cheese("Cheddar", "Good", "Yellow");
    echo $zargento->showType();
    echo "<br>";
    echo $zargento->showFlavor();
    echo "<br>";
    echo $zargento->showColor();
    echo "<br>";

    ?>[/PHP]

    Output:
    Code:
    Cheddar
    Good
    Yellow
    Cheese has been eaten
    It worked exactly how we wanted it to work.

    So far, we have covered classes, constructors and destructors, and inheritance. Now we can move on to a concept called encapsulation.

    Encapsulation is the idea of hiding information. For example, if you have class Car, and it has a function called giveBrand(). Now suppose you make a subclass of Car called Toyota. A Toyota object, when giveBrand() is used, will return 'Toyota'. But what if someone makes a Car object? Since a car is a generic term, giveBrand() won't really serve much purpose. What do you do?

    Encapsulation helps solve this problem. There are three keywords involved with encapsulation. These are:

    Public - The method is available to the base class and all subclasses
    Protected - The method is available to only subclasses
    Private - The method is available only to the base class

    Let's see an example using our Cheese and MoreCheese classes:
    [PHP]<?php

    class Cheese {
    var $type;
    var $flavor;
    var $color;

    function __construct($atype, $aflavor, $acolor) {
    $this->type = $atype;
    $this->flavor = $aflavor;
    $this->color = $acolor;
    }

    protected function giveDetails ($thetype, $theflavor, $thecolor) {
    $this->type = $thetype;
    $this->flavor = $theflavor;
    $this->color = $thecolor;
    }

    function showType() {
    return $this->type;
    }
    function showColor() {
    return $this->color;
    }
    function showFlavor() {
    return $this->flavor;
    }

    function __destruct() {
    echo "Cheese has been eaten";
    }
    }

    class MoreCheese extends Cheese {
    var $cost;

    function giveCost($f) {
    $this->cost = $f;
    }

    function showCost() {
    return $this->cost;
    }
    }

    $zargento = new Cheese("Cheddar", "Good", "Yellow");
    $zargento->giveDetails("Gorgonzola", "Awful", "Green and white");
    echo $zargento->showType();
    echo "<br>";
    echo $zargento->showFlavor();
    echo "<br>";
    echo $zargento->showColor();
    echo "<br>";

    ?>[/PHP]

    Output:
    Code:
    Fatal error: Call to protected method Cheese::giveDetails() from context '' in \yada\yada\yada on line 48
    See what happens? Since we protected the giveDetails() function, that means base class Cheese can't access it. We have to do the following:

    *. Make another function in MoreCheese to access the protected function
    2. Change $zargento from Cheese to MoreCheese.

    Step #* is done like so:

    [PHP]class MoreCheese extends Cheese {
    var $cost;

    function newGiveDetails ($thetype, $theflavor, $thecolor) {
    parent::giveDetails($thetype, $theflavor, $thecolor);
    }

    function giveCost($f) {
    $this->cost = $f;
    }

    function showCost() {
    return $this->cost;
    }
    }[/PHP]

    As you see, we used 'parent::' to get the function details of the giveDetails() function and put them in the newGiveDetails() function.

    Step #2 is just a simple change. Let's see the final result:

    [PHP]<?php

    class Cheese {
    var $type;
    var $flavor;
    var $color;

    function __construct($atype, $aflavor, $acolor) {
    $this->type = $atype;
    $this->flavor = $aflavor;
    $this->color = $acolor;
    }

    protected function giveDetails ($thetype, $theflavor, $thecolor) {
    $this->type = $thetype;
    $this->flavor = $theflavor;
    $this->color = $thecolor;
    }

    function showType() {
    return $this->type;
    }
    function showColor() {
    return $this->color;
    }
    function showFlavor() {
    return $this->flavor;
    }

    function __destruct() {
    echo "Cheese has been eaten";
    }
    }

    class MoreCheese extends Cheese {
    var $cost;

    function newGiveDetails ($thetype, $theflavor, $thecolor) {
    parent::giveDetails($thetype, $theflavor, $thecolor);
    }

    function giveCost($f) {
    $this->cost = $f;
    }

    function showCost() {
    return $this->cost;
    }
    }

    $zargento = new MoreCheese("Cheddar", "Good", "Yellow");
    $zargento->newGiveDetails("Gorgonzola", "Awful", "Green and white");
    echo $zargento->showType();
    echo "<br>";
    echo $zargento->showFlavor();
    echo "<br>";
    echo $zargento->showColor();
    echo "<br>";

    ?>[/PHP]

    Output:
    Code:
    Gorgonzola
    Awful
    Green and white
    Cheese has been eaten
    Due to length constraints, we will cover the opposite of protected, private, in part 2.5
    "Workers of the world unite; you have nothing to lose but your chains." -Karl Marx

  2. #2
    Join Date
    Sep 2006
    Posts
    1,649
    Your explanation of encapsulation is better; it explains why encapsulation would help, in a general sense. But you forgot one other reason:

    #* - It makes people think your an awesome coder implementing the newest coding paradigms.
    "Workers of the world unite; you have nothing to lose but your chains." -Karl Marx

+ Reply to Thread

Similar Threads

  1. OOP in PHP Part 2.5 - Encapsulation (Private)
    By Moonbat in forum Programming
    Replies: 0
    Last Post: 07-27-2008, 04:56 PM
  2. OOP in PHP Part One - Classes and Inheritance
    By Moonbat in forum Programming
    Replies: 1
    Last Post: 07-27-2008, 01:43 PM
  3. Telnet Hacking Part 2.
    By carlo in forum Internet Privacy
    Replies: 3
    Last Post: 12-19-2005, 11:19 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts