Chapter 2. Basic Concepts in OOP

Two elements are needed to form a truth—a fact and an abstraction.

Beware how you trifle with your marvelous inheritance, this great land of ordered liberty, for if we stumble and fall, freedom and civilization everywhere will go down in ruin.

Everybody gets everything handed to them. The rich inherit it. I don’t mean just inheritance of money. I mean what people take for granted among the middle and upper classes, which is nepotism, the old-boy network.

Our normal waking consciousness, rational consciousness as we call it, is but one special type of consciousness, whilst all about it, parted from it by the filmiest of screens, there lie potential forms of consciousness entirely different.

If you’re new to OOP, don’t expect everything to make sense right away. As you use OOP more and more, you’ll experience little “aha!” moments when the pieces begin to come together. PHP does have important OOP features, and it has its own way of implementing these features in the language. If you are familiar with other OOP languages, you can be assured that PHP is different in places—like allowing constants to be a part of an interface. Understanding abstraction is a cornerstone in both OOP and design patterns, and the more you use it, the more sense it makes.

The notion of abstraction is so essential to both object-oriented programming and design patterns that it bears more than a fleeting consideration. The general idea of abstraction in computing is not unlike the abstractions we use every day in natural language. For example, the word dog denotes a phenomenon that has dog-like characteristics. If someone says, “look at the dog,” they use the abstraction of dog (in other words, the word dog) to indicate a concrete instance of an animal with dog-like features. By using the words dog and cat, we can differentiate one from the other and point to lots of different dogs and cats. However, if we use the word “dog” to indicate a cat, we may be corrected. “That’s not a dog. It’s a cat.” So while abstractions are general, they are specific enough so that we can differentiate specific instances.

In Object-Oriented Design with Applications, 3rd Edition (Addison-Wesley), Grady Booch, a pioneer in both OOP and design patterns, has a clear definition of abstraction that nicely sums it up:

Abstraction is important because it allows programmers to group and classify objects. To some extent, all classes are abstractions of a set of operations on data. Keep the following in mind about abstractions:

Think about this paradox: abstractions are concrete methods for handling complexity. We group similarities in reality (abstract concrete likeness) to make them more manageable to work with. So instead of, “my loyal, bold, furry-faced, tail-wagging, face-licking, wet-nosed friend whose name is SyntaxError,” I can say, “my dog.”

Besides regular classes, PHP also has what are called abstract classes. In OOP and design patterns, abstract classes provide an organizing mechanism for your project. An abstract class cannot be instantiated, but rather a concrete class (one you can instantiate) inherits its interface and any concrete properties from the abstract class.

Before continuing, the term interface needs to be examined. Familiar interfaces include user interfaces, hardware interfaces, and other kinds of linkages involving computer hardware and software. Another kind of interface is one that describes the outline of an object. To begin, consider a simple class with a single method:

<?php
 class OneTrick
 {
     private $storeHere;
     public function trick($whatever)
     {
         $this->storeHere=$whatever;
         return $this->storeHere;
     }
 }

$doIt=new OneTrick();
$dataNow=$doIt->trick("This is perfect.");
echo $dataNow;

?>

The central part of an interface is made up of all the signatures in the class defined by its operations (functions). A signature consists of an operation’s name and parameters. Signatures also include the return data type, but because of the nature of data typing in PHP, we’ll have to return to this third element of a signature further on in the section Type Hinting: Almost Data Typing. Figure 2-1 shows the trick() method’s signature.

When you take all of an object’s signatures, it is the interface. For example, the OneTrick class has one operation with one signature made up of the name trick() and a single parameter, $whatever.

To write the trick() function as an abstract one, include the interface but nothing else:

abstract public function trick($whatever);

If a class has at least one abstract method, it must be an abstract class. However, an abstract class can have concrete methods as well. For example, the following class is abstract and includes an abstract method:

<?php
 abstract class OneTrickAbstract
 {
     public $storeHere;
     abstract public function trick($whatever);
 }
?>

In addition to the abstract method, you can see a single variable, $storeHere. A variable that is part of a class is a property. In some contexts, a reference to both properties and methods is simply properties, but for the most part properties refer to variables and constants (abstract data) and methods refer to functions (operations on the data).

PHP does not have abstract properties as such. You can declare a property with no assigned value and treat it as an abstract property, but unlike abstract methods, you are not forced to use them.

If you declare an abstract method in an abstract class, you must implement it in each child class that inherits the parent. It might help to think about methods in abstract classes as being like a contract that forces a set of hierarchies for all subclasses, so that they must all follow the same standards. For now, begin thinking of abstract classes as you would containers that can be filled with just about anything and placed on ships, trucks, and trains. The containers, like abstract classes, are part of a larger structure.

A class that inherits from a class is a child class, and the abstract class (or any other class from which another class has inheritance) is the parent class. The following shows how to implement the abstract class, OneTrickAbstract:

<?php
include_once('OneTrickAbstract.php');

class OneTrickConcrete extends OneTrickAbstract
{
    public function trick($whatever)
    {
        $this->storeHere="An abstract property";
        return $whatever . $this->storeHere;
    }
}

$worker=new OneTrickConcrete();
echo $worker->trick("From an abstract origin...");
?>

Abstract methods can be implemented in any way you want as long as you include the method’s signature and correct visibility. In this case, that signature includes the name “trick” and a single parameter, $whatever, and the visibility is public. The following are all legitimate implementations of the trick() method:

public function trick($whatever)
{
    $echo $whatever;
}

Or:

public function trick($whatever)
{
    $half=$whatever/2;
    return $half;
}

Or:

public function trick($whatever)
{
    $this->storehere=25;
    $quarter=$whatever * 100;
    return ($quarter / $this->storehere);
}

You may wonder what the point is in an abstract method if you can revise it as long as you maintain the signature and visibility. In the Inheritance section of this chapter, you will be able to see more clearly why inheriting the interface is important.

While abstract classes generally have some abstract methods, you can add as many concrete methods and properties as you want in addition to any abstract methods that must be implemented. However, an abstract class can consist of nothing but concrete methods.

PHP 5.4 has a structure called Traits that are mechanisms for code reuse where multiple inheritance is not allowed. A class may inherit one class and then at the same time use a Trait that functions something like multiple inheritance. They will not be used in the examples in this book and are mentioned here in case there may be some pattern example in another language that uses multiple inheritance that you would like to implement in PHP.

Another OOP and design pattern building block is an interface. Like most abstract classes, interfaces have abstract methods. However, you cannot include concrete methods in an interface or variables as in an abstract class. (In an exception to abstractness, you can include concrete constants in an interface, but that is a unique feature of PHP interfaces.) The salient point about interfaces is that they are important structural elements in OOP and design patterns.

To create an interface, use the interface statement instead of class. As a general convention, interfaces begin with the letter I or i; in this book, we’ll use a capital I followed by a capital letter describing the interface. This is followed by abstract methods, but the abstract statement is not used. The following is a simple interface with three methods:

<?php
interface IMethodHolder
{
    public function getInfo($info);
    public function sendInfo($info);
    public function calculate($first,$second);
}
?>

To implement an interface, use the implements statement instead of extend as is done with abstract classes. Note that the listing uses the include_once() function to make the interface available to the class implementing it:

<?php
include_once('IMethodHolder.php');

class ImplementAlpha implements IMethodHolder
{
    public function getInfo($info)
    {
        echo "This is NEWS! " . $info . "<br/>";
    }
    public function sendInfo($info)
    {
        return $info;
    }
    public function calculate($first,$second)
    {
     $calulated = $first * $second;
     return $calulated;
    }
    public function useMethods()
    {
        $this->getInfo("The sky is falling...");
        echo $this->sendInfo("Vote for Senator Snort!") . "<br/>";
        echo "You make $" . $this->calculate(20,15) . " in your part-time 
         job<br/>";
    }
}

$worker=new ImplementAlpha();
$worker->useMethods();
?>

When you test the program, you should see the following output:

This is NEWS! The sky is falling...
Vote for Senator Snort!
You make $300 in your part-time job

Note that in addition to implementing the three methods in the interface, the ImplementAlpha class includes a third method, useMethods(). As long as you implement the full number of methods in the interface, you can add as many other methods and properties as you need.

While you cannot include variables in interfaces, you can include constants. In order to use constants, you need the scope resolution operator (::). The double colon operator can be used to allow access to constants, both in classes and through an interface implementation. The general format can be seen in the following code samples:

$someVariable= InterfaceName::SOME_CONSTANT;

For example, the following interface has constants used in a MySQL connection:

<?php
interface IConnectInfo
{
    const HOST ="localhost";
    const UNAME ="phpWorker";
    const DBNAME = "dpPatt";
    const PW ="easyWay";
    function testConnection();
}
?>

Implement the interface just like any other PHP interface. The values of the constants can then be passed using the scope resolution operator in the implementation:

<?php
include_once('IConnectInfoMethod.php');

class ConSQL implements IConnectInfo
{
    //Passing values using scope resolution operator
    private $server=IConnectInfo::HOST;
    private $currentDB= IConnectInfo::DBNAME;
    private $user= IConnectInfo::UNAME;
    private $pass= IConnectInfo::PW;

    public function testConnection()
    {
      $hookup=new mysqli($this->server, $this->user, $this->pass, 
        $this->currentDB);

        if (mysqli_connect_error())
        {
            die('bad mojo');
        }

        print "You're hooked up Ace! <br />" . $hookup->host_info;

        $hookup->close();
    }
}
$useConstant = new ConSQL();
$useConstant->testConnection();
?>

The only method is testConnection(), but your interface could be made up of nothing but constants if you wanted. The values are passed to the class properties (private variables in the example) using the name of the interface (IConnectInfo), the scope resolution operator, and the name of the constant.

One of the important structural elements in the abstraction in OOP and design patterns is typing data to an interface instead of an implementation. This means that the reference to the data is through the parent class, typically an interface or abstract class. (In this context, interface is used to refer to either an interface or abstract class.)

The basic format for type hinting is as follows:

function doWork(TypeHint $someVar)...

Type hints must be the name of a class or interface. In design pattern work, an abstract class or interface is preferred because it does not bind the type of an implementation, just the structure. The following example shows an interface with two implementations of the interface and a class that uses an interface in type hinting to establish a loose but clear bind.

Interface
//IProduct.php
<?php
interface IProduct
{
    function apples();
    function oranges();
}

?>
FruitStore Implementation
//FruitStore.php
<?php
include_once('IProduct.php');

class FruitStore implements IProduct
{
    public function apples()
    {
        return "FruitStore sez--We have apples. <br/>";
    }

    public function oranges()
    {
        return "FruitStore sez--We have no citrus fruit.<br/>";
    }
}
?>
CitrusStore Implementation
//CitrusStore.php
<?php
include_once('IProduct.php');

class CitrusStore implements IProduct
{
    public function apples()
    {
        return "CitrusStore sez--We do not sell apples. <br/>";
    }

    public function oranges()
    {
        return "CitrusStore sez--We have citrus fruit.<br/>";
    }
}

?>
Object with type hinting
//UseProducts.php
<?php
include_once('FruitStore.php');
include_once('CitrusStore.php');

class UseProducts
{
    public function __construct()
    {
        $appleSauce=new FruitStore();
        $orangeJuice=new CitrusStore();
        $this->doInterface($appleSauce);
        $this->doInterface($orangeJuice);
    }

    //IProduct is type hint in doInterface()

    function doInterface(IProduct $product)
    {
        echo $product->apples();
        echo $product->oranges();
    }
}

$worker=new UseProducts();
?>

When you test the UseProducts class, the output displays the following:

FruitStore sez--We have apples.
FruitStore sez--We have no citrus fruit.
CitrusStore sez--We do not sell apples.
CitrusStore sez--We have citrus fruit.

What you see on the screen are different implementations of the IProduct interface. The crucial feature to note is that in the doInterface() method, the type hint of IProduct recognizes both of the classes that implemented the IProduct interface. In other words, instead of recognizing one as a FruitStore instance and the other as a CitrusStore instance, it recognizes their common interface IProduct.

In practical terms for development, enforcing data types ensures that any object (class) used in conjunction with a given method where code hinting is used will have a given interface. Further, if an interface (either an abstract class or interface) is used as the code hint, the binding is much looser; it is bound to the interface instead of a specific implementation. As your programs get bigger, you can make changes as long as you adhere to an interface. At the same time, you can do so without getting entangled in concrete implementations.

You cannot use scalar types like string or int for code hints, but you can use arrays, interfaces (as in the previous example), and classes. So while not as flexible as some other languages, the implementation of class typing in PHP through type hinting serves a crucial function in OOP and design pattern programming.

Often when you read about encapsulation you will encounter the phrase information hiding. The phrase is not inaccurate, but it makes more sense once you understand encapsulation; it’s not always helpful in explaining encapsulation to begin with the concept of information hiding. Instead, a better beginning is the image of compartments. Grady Booch provides the following description:

Once a big complex problem has been modularized into solvable subproblems, encapsulation is a way of taking the smaller abstractions and compartmentalizing them.

You encounter encapsulation in everyday life. Take, for example, going for a drive in your car. The car is made up of many objects, and you have little idea of how most of them work. The ignition starts the engine, but you may not know much about the battery-powered starter motor, the details of the internal combustion engine, or the electrical system in your car. You just put the key in the ignition and rotate it to start the car. The complexities of the details are hidden from you, and you have access to them in only certain ways. You are working with an encapsulated system. You don’t need to know how something works, you just need to know how to access control mechanisms—think of it as a user interface (UI) for your car.

As you are driving down the road with the window down, suppose that a car pulls up next to you, and a person sticks her arm out the window of the other car and tries to grab your steering wheel and steer your car. You can think of that as breaking encapsulation. You don’t want that to happen, so you roll up your window so that no one outside the car has access to the encapsulated cocoon of you driving your car.

In programming, encapsulation is what makes an object an object. An object has certain features that surround it so that access to its functionality is controlled by the structure of the program—just like the structure of your car controls access to its many parts. A class is encapsulated through limited access to its methods and properties. You don’t want outside influences to take control of the properties of the class and use them or change their state except through explicit routes—just like you don’t want someone to grab the steering wheel away from you. So when you encounter information hiding in the context of encapsulation, what it means is that the details of a module may be hidden so that the module may be used through the appropriate access channels and not through the module’s details.

In PHP, the term visibility refers to the access to the properties of a class. (The term access is used in other languages and accessors for the types of access.) Like other OOP languages, PHP uses three kinds of visibility: private, protected, and public. These visibilities are ways that programs can be encapsulated and accessed for use.

While private visibility of a property provides access only to elements within the same class, protected visibility allows access to both the same class and child classes. You can incorporate protected visibility with both abstract and concrete methods. The following example shows how using an abstract class and a concrete implementation use protected visibility:

<?php
//ProtectVis.php
abstract class ProtectVis
{
    abstract protected function countMoney();
    protected $wage;

    protected function setHourly($hourly)
    {
        $money=$hourly;
        return $money;
    }
}
?>

When a child class extends an abstract class with protected methods, it must implement the abstract method before using it. The child class can use the protected concrete method without further implementation:

<?php
//ConcreteProtect.php
include_once('ProtectVis.php');

class ConcreteProtect extends ProtectVis
{
    function __construct()
    {
        $this->countMoney();
    }
    protected function countMoney()
    {
        $this->wage="Your hourly wage is $";
        echo  $this->wage . $this->setHourly(36);
    }
}
$worker=new ConcreteProtect();
?>

Note that the abstract method countMoney() incorporates the inherited setHourly() method. All inherited properties and methods require the $this statement. The initial access to the protected properties is through the public constructor function.

While not as encapsulating as private visibility, protected visibility has the capacity to encapsulate larger structures in a program. A parent class, whether abstract or concrete, and its child classes make up the larger structure.

In order to maintain encapsulation while at the same time having accessibility, OOP design suggests using getters and setters (also called accessors and mutators, respectively). Instead of accessing a class directly and either obtaining or changing property values through direct assignment, the getter/setter function does this for you. In general, the use of getters and setters must be done judiciously; too many can break encapsulation. The following example shows one use of getters and setters in a PHP class:

<?php
//GetSet.php
class GetSet
{
    private $dataWarehouse;

    function __construct()
    {
        $this->setter(200);
        $got= $this->getter();
        echo $got;
    }

    private function getter()
    {
        return $this->dataWarehouse;
    }

    private function setter($setValue)
    {
        $this->dataWarehouse=$setValue;
    }
}
$worker=new GetSet();

?>

The getter/setter functions are private, and so access is encapsulated. Further, in this implementation, the setter value is inside the class and so it functions as a rather large data holder.

In dealing with data in object-oriented systems, Allen Holub, in Holub on Patterns (Apress) suggests the following:

Don’t ask for the information you need to do the work; ask the object that has the information to do the work for you.

In the GetSet class example, instantiation of the class:

$worker=new GetSet();

does that nicely. It does not expose the implementation details. However, in isolation, the GetSet class doesn’t look too useful because the only way to assign a value is to hardcode it into the class.

In part, the purpose of design patterns is to set up the communication links between objects. Much of what passes as OOP misuses getters and setters, and making access public to them only breaks encapsulation. The following explanation, from “Single Responsibility Applied to Methods” (http://tinyurl.com/9256gey), of object-oriented programming compared to procedural programming by David Chelimsky helps clear up the role of communications in OOP:

In procedural programming, a process is expressed in one place in which a series of instructions are coded in order. Whereas in OO, a process is expressed as a succession of messages across objects. One object sends a message to another, which does part of the process and then sends a new message off to another object, which handles part of the process, etc. You modify a process by reorganizing the succession of messages rather than changing a procedure.

The process of maintaining encapsulation while communicating between objects (classes) is part of a design pattern’s job. Working out a way to establish communication without breaking encapsulation can be tricky, and so design patterns become a sort of “cheat sheet” on how to set up a program using communicating classes.

At its core, inheritance is a simple concept. A class that extends another class has all of the other class’ properties and methods. This allows developers to create new classes that extend the functionality of other classes. For example, if you have a class, FurryPets, you can extend it to Dogs and Cats with both classes inheriting the properties of FurryPets while extending it to differentiate Dogs and Cats. The following shows a simple PHP example:

FurryPets.php
<?php
//FurryPets.php
class FurryPets
{
    protected $sound;
    protected function fourlegs()
    {
        return "walk on all fours";
    }

    protected function makesSound($petNoise)
    {
        $this->sound=$petNoise;
        return $this->sound;
    }
}
?>
Dogs.php
<?php
//Dogs.php
include_once('FurryPets.php');
class Dogs extends FurryPets
{
    function __construct()
    {
        echo "Dogs " . $this->fourlegs() . "<br/>";
        echo $this->makesSound("Woof, woof") . "<br/>";
        echo $this->guardsHouse() . "<br/>";
    }

    private function guardsHouse()
    {
        return "Grrrrr" . "<br/>";
    }
}
?>
Cats.php
<?php
//Cats.php
include_once('FurryPets.php');
class Cats extends FurryPets
{
    function __construct()
    {
        echo "Cats " . $this->fourlegs() . "<br/>";
        echo $this->makesSound("Meow, purrr") . "<br/>";
        echo $this->ownsHouse() . "<br/>";
    }

    private function ownsHouse()
    {
        return "I'll just walk on this keyboard." . "<br/>";
    }
}

?>
Client.php
<?php
//Client.php
include_once('Dogs.php');
include_once('Cats.php');
class Client
{
    function __construct()
    {
        $dogs=new Dogs();
        $cats=new Cats();
    }
}
$worker=new Client();
?>

The Client class makes the requests, and constructor functions in the dogs and cats objects generate the following output:

Dogs walk on all fours
Woof, woof
Grrrrr

Cats walk on all fours
Meow, purrr
I'll just walk on this keyboard.

The fourlegs() method generates identical output for both objects; the makesSound() output depends on the argument in the parameter; and finally, each class has its own unique method—guardsHouse() and ownsHouse().

Inheritance helps structure the different classes that may make up a program. However, in order to keep the binding between classes loose, inheritance typically comes from abstract classes, and it is shallow—a single level of child classes. If programs are bound to deep levels of inheritance of concrete classes, even simple changes in the parent classes can wreak havoc on the child classes.

At its base, polymorphism refers to many forms, but that’s not very helpful unless you understand it in the context of OOP. The real value of polymorphism is that objects with the same interface can be called to do different things. In a large complex structure (a great big program), additions and changes can blow the hinges off your program unless it has a common interface (from a parent class or interface). For example, the following program has two classes that share a common interface. The implementations of the interface are quite different:

<?php
//Poly.php
interface ISpeed
{
    function fast();
    function cruise();
    function slow();
}

class Jet implements ISpeed
{
    function slow()
    {
        return 120;
    }

    function cruise()
    {
        return 1200;
    }

    function fast()
    {
        return 1500;
    }
}

class Car implements ISpeed
{
    function slow()
    {
        $carSlow=15;
        return $carSlow;
    }

    function cruise()
    {
        $carCruise=65;
        return $carCruise;
    }

    function fast()
    {
        $carZoom=110;
        return $carZoom;
    }
}

$f22=new Jet();
$jetSlow=$f22->slow();
$jetCruise=$f22->cruise();
$jetFast=$f22->fast();
echo "<br/>My jet can take off at $jetSlow mph and cruises at $jetCruise mph. 
However, I can crank it up to $jetFast mph if I'm in a hurry.<br/>";

$ford=new Car();
$fordSlow=$ford->slow();
$fordCruise=$ford->cruise();
$fordFast=$ford->fast();
echo "<br/>My car pokes along at $fordSlow mph in a school zone and cruises at 
$fordCruise mph on the highway. However, I can crank it up to $fordFast mph 
if I'm in a hurry.<br/>";
?>

The two implementations of the ISpeed interface by the Jet and Car classes are very different. However, when making changes or additions within a given structure of a program, I can request or use the interface methods without having to worry about whether my program will crash or not.

The easiest way to see polymorphism is in the different implementations of an interface, as was done in the previous Poly.php example. The Jet class simply implements each method to return a primitive value, and the Car class first passes a primitive value to a variable and returns the variable’s value. Both used the same interface.

One caution about using polymorphism with PHP classes and interfaces is that the return types are not included in a PHP function’s signature. For example, a signature in C# would include both the type of return data and whether or not a return is expected. For example, consider the following C# snippet where an interface is declared:

//C# Interface
interface IFace
{
    string stringMethod();
    int numMethod(int intProp);
    void noReturnMethod();
}

The C# language does not require the keyword function to be included in any of its methods—just the signature, made up of the return data type, name, and parameters (if any). So the first method—stringMethod()—expects a string to be returned, and any implementation of the method must include the return keyword. Likewise, the second method—numMethod()—expects an integer to be returned, and the method must include an integer parameter. Again, any implementation requires a return statement. However, the third method—noReturnMethod()—has a return type of void. That means that no return statement is expected in the implementation of the method. In fact, if a return were included in the implementation of the method with a void data type, it would cause an error and failure.

In PHP, where no return information is included in the method’s signature, you can run into possible trouble if you have mixed implementations with different data types and with and without return values. The value of polymorphism is that even though the forms may be different, you should be able to depend on the interface to guide your implementations. The more information in the interface—such as what type of behavior (returned data or not) and data type is expected—the easier it is to have different forms that still work together. In the Poly.php example, all of the methods included an integer and a return statement. So while PHP does not have a very strong signature, you can enforce it in your planning and implementation. You can do so using comment statements in your interface. For example:

//PHP Interface
interface IFace
{
//@return string
function stringMethod();

//@return integer and use integer property
    function numMethod($intProp);

    //do not use return
    function noReturnMethod();
}

If you have an extended virtual signature in your interfaces (including abstract classes) using comments, you can extend the advantages of a strongly typed language.

This chapter has included the most key OOP concepts in one place you will find in this book. However, as you read each chapter and design pattern, you will find that these concepts will be reintroduced by pointing to some aspect of the design pattern or in a PHP implementation of a design pattern. So keep in mind that what may not make sense now should become clearer as you continue with the design patterns. Chapter 3 introduces some key design pattern concepts that are based on OOP concepts and ideas.