PHP - Object-Oriented Programming

Before OOP, software programs were incresingly becoming very large and complex. These systems needed many architects and engineers to develop the software, and more time and money were spent on maintenance. Often, if new features or policies needed to be added or changed to reflect the business model, it would take several weeks or even months to modify the software while it look much less time building a new application.

So what makes OOP different from functional programming? When we code an application with functions, we create programs that are code-centric. These applications call function by function consecutively. The data is first sent as the input, the function does the actual transformation, and then it returns the corresponding output. OOP takes the opposite approach since it is data-centric. Objects, which represent their data internally, contain functionality called methods.

When we develop our applications, we can divide our programs into parts, or large modules, such as different presentation layers, database access objects, search engines and security components. When developing our modules as large, singular units, we are guaranteed to ensure that changes to one object will not affect another. Likewise, we may able to reuse components accross several applications. We can also break these modules down even further by using sub-modules and even further to single objects, which is the smallest component in an object-oriented program. Next, we will looking at the smallest component in an object-oriented program, which is the class.

Classes

A class is the definition or representation of a specific type of data and classes serve as a way to model all the different types of objects in our system.

class ClassName [extends ParentclassName]
{
         var $member1;
         var $member2;
         ...
         var $memberN;
         
         //Constructor
         function ClassName()
         {
         }

         function method1()
         {
         }
         ...
         function methodN()
         {
         }
}

A class in PHP contains three main components: members (data or attributes) , methods, and constructors. A member is a piece of data that the object contains. Methods are the services that the object provides to its clients that use and manipulate its internal members. A constructor is a special method that initializes the object into its ready state.

Objects

An object in our program is an instance of a class. The reason why it's called an instance is because we can create multiple objects (or instances) of the same class just like there can be many cars on the road of the same class. To create two new cars, all we would need to do is to execute these lines of code in our program.

<?php
$car1 = new Car();
$car2 = new Car();

We use the new keyword to construct new instances of a class, that is, create a new object. When we create an object or instance of a class, we say that the object has been instantiated. The reference to the newly instantiated object is then placed into the variables $car1 and $car2, respectively.

If we want to start a car, we would call its start() method like this:

$carStarted = $car1->start($key);


if($carStarted) echo("Car has started.");

And if we wanted to stop the car, we would do the following:

  $car1->stop();
?>

You'll notice that this object has an easy interface to use. You don't have to know how it's been developed. This idea of creating easy-to-use objects is leading to the next section, Encapsulation.

Encapsulation

An Encapsulating gain the benefit of hiding some private data from being access or control them. Unfortunately, PHP does not have this feature at present, but following good coding practices difinitely helps. A good rule of thumb is to design your class such that it has services to accomplish everything you intend to do with the object. Never access members ourside the class and always encapsulate your classes properly to reap the benefits of information hiding. Some languages offer the ability to disallow access to members altogether by making them private (or protected) to the class only.

Inheritance

This is the basic building blocks of an object-oriented program and some good heuristics. With inheritance, we can put the details of similar types of an objects in their own respective locations and also consolidate the similarities in a base object. We will start with building the base class (also called parent class or super class) as follow:

<?php
class employee{
         var $name;
         var $position;
         var $salary;

         function employee($name, $position, $salary){
               $this->name = $name;
               $this->position = $position;
               $this->salary = $salary;
         }

         function working(){
               echo($this->name." is working");
         }

         function getSalary(){
               echo("Paying salary ".$this->salary." for ".$this->name);
         }
}
?>

The code define a class that represent the general employee with some basic activities-like functions such as working or getting salary. Now we go next to define some specialized class from this parent class. A specialized class of a parent is either called a child class or a subclass.

<?php
class manager extends employee{
        function manager($name, $position, $salary){

             //declare manager to be one of employee with name
             $this->employee($name, $position, $salary);
             $this->special_duty = $duty;
        }

        function working(){
            echo($this->working());
            echo(" and working harder");
        }
}
?>

The extends keyword is used to inherit the properties of employee. We assume that all employees in the company have their name and position, also they can work and get salary. The manager is one of the employee but different in salary and work responsibilities. Now let's see how we can use this classes.

<?php
$emp1 = new employee("Bob", "Programmer", 1500);
$emp1->working();  //Prints Bob is working
$emp1->getSalary(); //Prints Paying salary 1500 for Bob

$emp2 = new manager("John", "System Analyst", 4500);
$emp2->working(); //Prints John is working and working harder
$emp2->getSalary(); //Prints Paying salary 4500 for John
?>

Notice that Bob and John is both the employee of the company but different in position and salary, also different in responsibilities and work type. John has all properties that employee has plus the properties of manager whereas Bob has the properties only in employee class.

Polymorphism

Polymorphism is an object-oriented feature that gives us the ability to treat an object in a generic manner. We can invoke a behavior on existing classes and any new classes defined in the future, leaving the details and differences to the interpreter at run time. Polymorphism makes it very easy to add new types to a system without breaking existing code.

$AllEmployees = array(new employee(...), new manager(...), new employee(...),
                                  new manager(...));


foreach($AllEmployees as $employee){
    $employee->working();
    $employee->getSalary();
    echo("<br><br>");
} //Prints info of 2 employees and 2 managers in array

$AllEmployees[] = new employees(...);

foreach($AllEmployees as $employee){
    $employee->working();
    $employee->getSalary();
    echo("<br><br>");
} //Prints info of 3 employees and 2 managers

Notice that the foreach statement did not have to change. Polymorphism enables us to write such maintainable code. We use inheritance to take advantage of polymorphism to give us clean, maintainable code. Inheritance is not only a method for reusing code as stated above, but is also used to achieve polymorphism in application code.

Abstract Methods

When we use inheritance, often times the parent class will contain methods that have no code because it is impossible to specify common behavior. Therefore, we use a concept called an abstract method to indicate that a method contains no code and the implementor of any possible subtypes must implement the behavior for that method. If the method is not overridden, it will continue to provide no behavior.

In object-oriented terminology, abstract methods usually force the implementor to override the method. Howover, in PHP this is not the case due to limitations in its object-oriented features. Implementors of subtypes should look at the documentation for the class they want to create subtypes for to see what abstract methods are needed to be overridden to have a properly implemented subtype.

<?php
class employee{
         var $name;
         var $position;
         var $salary;

         function employee($name, $position, $salary){
               $this->name = $name;
               $this->position = $position;
               $this->salary = $salary;
         }

         function working(){
               echo($this->name." is working");
         }

         function getSalary(){
               echo("Paying salary ".$this->salary." for ".$this->name);
         }

         //Abstract method
         function delegate(){ }
}
?>

This abstract method will make the employee class incomplete untill we inherit and define delegate method. If you fail to define an abstract method and your subtypes do not overridden it, you will receive a PHP runtime error specifying that the method does not exist in the object.

<?php
class manager extends employee{
        function manager($name, $position, $salary){

             //declare manager to be one of employee with name
             $this->employee($name, $position, $salary);
             $this->special_duty = $duty;
        }

        function working(){
            echo($this->working());
            echo(" and working harder");
        }

        function delegate(){
            echo("Delegating Jobs");
       }
}
?>

As you can see, the manager class override the abstract method from employee and make code complete. So we can use the manager class in our code now. This is the concept of having abstract classes and how they are used in PHP.