Object Oriented Programming is a very important concept for programmers to solve real-life problems. This article explaining the concept of object-oriented programming and its features.
- Object: Everything in this world is surrounded with objects. Table, chair, monitor, cellphone everything is an object. There are two things in an object to remember to solve real-life problems. One is attribute and the other one is behavior. If we talk about monitor so…model number, screen size all these are attributes. On the other hand, the features like volume up or volume down are behavior for the monitor. In programming, variables are attributes and functions are behavior.
Example:
<?php
// Class definition
class
TV {
// Member variables
public
$model
=
'xyz'
;
public
$volume
= 1;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
}
// Create new object
$tv_one
=
new
TV;
// Calling member function
$tv_one
->volumeUp();
echo
$tv_one
->volume;
?>
Output:2
In the above example, creating an object $tv_one of TV class and implementation of function showing the behavior of the object. Initially $tv_one->volume was 1. After calling its function volume has been increased and displaying the updated result. $this refers to the particular or current object. You can create multiple objects and show it’s behavior. Implementing this code will have the benefit of code re-usability and code will be easy to manage in the future.
- Constructor function: Constructor function is an special function for which do not need to call the function like earlier we were doing after creating an object.
Example:
<?php
// Class definition
class
TV {
// Member variables
public
$model
;
public
$volume
;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
function
__construct(
$m
,
$v
) {
$this
->model =
$m
;
$this
->volume=
$v
;
}
}
// Create new object
$tv
=
new
TV(
'xyz'
, 2);
echo
$tv
->model;
?>
Output:xyz
In the above example, assigned the value of model and volume when we are creating the object. This is the benefit of using a constructor function. You don’t need to change the model number for each and every project you will be making. All need to do is to include this file and when you need to create an object of TV and assign its value you can do that instantly while creating its object.
- Inheritance: In a simple word, inheritance means inheriting the properties or functionalities from one class to another class. Model and volume will find in all kinds of television but suppose you need to add additional feature timer. The timer can not be included in all the television. So it will use inheritance for that television which includes timer property. Use ‘extends’ keyword to implement inheritance.
Example:
<?php
// Class definition
class
TV {
// Member variables
public
$model
;
public
$volume
;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
function
__construct(
$m
,
$v
) {
$this
->model =
$m
;
$this
->volume=
$v
;
}
}
class
TvWithTimer
extends
TV {
public
$timer
= true;
}
// Create new object
$tv
=
new
TvWithTimer(
'xyz'
, 2);
echo
$tv
->model;
?>
Output:xyz
Here, TVWithTimer class is a child class for TV class, whereas TV class is a parent class. The TVWithTimer class inherited all the variables and functions from its parent class so all the variables and functions which are in TV class will be available in TvWithTimer. So create multiple classes and inherit the property from TV class. Another important thing is Method Overriding. If defining the constructor function in child class after inheriting all the properties from parent class then the priorities will be given to child class constructor instead of a parent class.
class
plazmaTv
extends
TV {
function
__construct {
}
}
$plazma
=
new
plazmaTv;
echo
$plazma
->model;
Here, no output will display and the screen will be blank because the child class constructor is being called and it has overridden the parent class constructor. The same logic also applies for variables and you can override the variables in a child class as well.
- Encapsulation: Encapsulation is all about wrapping the data and method in a single unit. Object-Oriented programming sets the access level for member functions or variables. It means from where it needs to be accessed. There are three kinds of access levels or access specifiers.
- Public: Public functions or variables can only be accessed from anywhere. In all the above examples, we are able to access the public functions and variables outside the class and everyone can call it.
- Private: Private functions or variables can only be accessed by the class who created it.
Example:
<?php
// Class definition
class
TV {
// Member variables
private
$model
;
public
$volume
;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
function
__construct(
$m
,
$v
) {
$this
->model =
$m
;
$this
->volume=
$v
;
}
}
// Create new object
$tv
=
new
TV(
'xyz'
, 2);
echo
$tv
->model;
?>
Output:
Cannot access private property TV::$model in /home/65af96133e297a6da6c1ad3d75c9ff46.php:28
The error will display after executing the above code. It means the function or variable not accessible outside the class.
- Protected: Protected functions or variables can only be used by the class who created and it’s child class means all the classes which inherit the property of parent class having protected method or variable.
Example:
<?php
// Class definition
class
TV {
// Member variables
protected
$model
;
public
$volume
;
// Member Functions
function
volumeUp() {
$this
->volume++;
}
function
volumeDown() {
$this
->volume--;
}
function
getModel() {
return
$this
->model;
}
function
__construct(
$m
,
$v
) {
$this
->model =
$m
;
$this
->volume=
$v
;
}
}
class
plazma
extends
TV {
function
getModel() {
return
$this
->model;
}
}
// Create new object
$tv
=
new
plazma(
'xyz'
, 1);
echo
$tv
->getModel();
?>
Output:xyz
- Abstract Classes: Like the keyword is saying, Abstract means not completed. Abstract classes are those classes where functions are declared but not implemented.
Example:
<?php
// Abstract class
abstract
class
ABC {
public
abstract
function
xyz();
}
class
def
extends
ABC {
public
function
xyz() {
echo
"Welcome to neveropen"
;
}
}
// Create new object
$obj
=
new
def;
echo
$obj
->xyz();
?>
Output:Welcome to neveropen
Here, we created an abstract class that has one abstract method but we haven’t implemented the method in ABC base class. All the classes which will extend ABC class will have the implementation for function XYZ. Here you can not make the object for ABC class. ABC class works as a base class for all it’s child classes and the implementation or object creation will be done for child classes. Declaring a class abstract class is enforcement that you don’t want to create a direct object for that class.
Example:
<?php
abstract
class
BaseEmployee {
protected
$firstname
;
protected
$lastname
;
public
function
getFullName() {
return
$this
->firstname.
" "
.
$this
->lastname;
}
public
abstract
function
getMonthlySalary();
public
function
__construct(
$f
,
$l
) {
$this
->firstname =
$f
;
$this
->lastname =
$l
;
}
}
class
FullTimeEmployee
extends
BaseEmployee {
protected
$annualSalary
;
public
function
getMonthlySalary() {
return
$this
->annualSalary / 12;
}
}
class
ContractEmployee
extends
BaseEmployee {
protected
$hourlyRate
;
protected
$totalHours
;
public
function
getMonthlySalary() {
return
$this
->hourlyRate *
$this
->totalHours;
}
}
$fulltime
=
new
FullTimeEmployee(
'fulltime'
,
'Employee'
);
$contract
=
new
ContractEmployee(
'Contract'
,
'Employee'
);
echo
$fulltime
->getFullName();
echo
$contract
->getFullName();
echo
$fulltime
->getMonthlySalary();
echo
$contract
->getMonthlySalary();
?>
Output:fulltime EmployeeContract Employee00
- Interfaces: There is a limitation for inheritance in PHP that is you can not extend multiple classes. Through Interface you can achieve multiple inheritance property. Interfaces also worked like abstract classes. The ‘implements’ keyword is used for interfaces. There is a difference between abstract class and interface class. In abstract class define variables but in the interface, the class can not define variables. It can also not create constructor function in interfaces. It can not declare a private or protected function.
Example:
<?php
interface
a {
public
function
abc();
}
interface
b {
public
function
xyz();
}
class
c
implements
a, b {
public
function
abc() {
echo
'neveropen '
;
}
public
function
xyz() {
echo
'A computer science portal'
;
}
}
// Create an object
$obj
=
new
c;
$obj
->abc();
$obj
->xyz();
?>
Output:neveropen A computer science portal
- Static Members: Static variables or static functions are directly related with class. It can access static variables or functions directly with the class names. Use the ‘static’ keyword to declare a static function or static variable.
Example:
<?php
// Class definition
class
abc {
public
static
$data
=
'neveropen '
;
public
static
function
xyz() {
echo
"A computer science portal"
;
}
}
echo
abc::
$data
;
abc::xyz();
?>
Output:neveropen A computer science portal
Example: This example count how many objects we have created for a class.
<?php
class
abc {
public
static
$objectCount
= 0;
public
static
function
getCount() {
return
self::
$objectCount
;
}
public
function
__construct() {
self::
$objectCount
++;
}
}
$a
=
new
abc();
$b
=
new
abc();
$c
=
new
abc();
$d
=
new
abc();
echo
abc::getCount();
?>
Output:4
Note: If created object instead of static using static function or variable every time the output will be 1. So static variable or keyword is related to class not object.
- Late Static Binding: In PHP 5.3 a concept of late static binding was introduced.
Example:
<?php
class
DB {
protected
static
$table
=
' basetable'
;
public
function
select() {
echo
'SELECT * FROM'
.self::
$table
;
}
public
function
insert() {
echo
'INSERT INTO'
.self::
$table
;
}
}
class
abc
extends
DB {
protected
static
$table
=
'abc'
;
}
$abc
=
new
abc;
$abc
->select();
?>
Output:SELECT * FROM basetable
Here, class DB extends class abc, but when running this code during compilation time it’s taking the table name from abc class, not DB. During the compilation time, the PHP interpreter immediately assigns the value from the parent class. In order to get the variable from the child, the class interpreter needs to assign the value during runtime instead of compilation time which is happening in the above example.
echo 'SELECT * FROM' .self::$table;
or
echo 'INSERT INTO' .self::$table;
Here when the interpreter will get the request it won’t assign the value during compilation time. It will be in pending for runtime. It will assign the value during runtime time and the output will be SELECT * FROM abc
- Polymorphism: Polymorphism means many types or many forms. It means suppose you have created an interface also classes that will implement this interface class. These classes will have different functionality and they all will share this common interface.
Create an interface with LoggerInterface name in LoggerInterface.php file.
<?php
interface
LoggerInterface {
public
function
log(
$message
);
}
?>
Now creating a file EmailLogger.php which will implement this interface.
<?php
class
EmailLogger
implements
LoggerInterface {
public
function
log(
$message
) {
echo
"Logging message to email: $message"
;
}
}
?>
Create another file FileLogger.php and implement the interface class.
<?php
class
FileLogger
implements
LoggerInterface {
public
function
log(
$message
) {
echo
"Logging message to file: $message"
;
}
}
?>
Another file is DBLogger.php
<?php
class
DBLogger
implements
LoggerInterface {
public
function
log(
$message
) {
echo
"logging message to DB: $message"
;
}
}
?>
Now, create a UserProfile.php file where call all these files by only defining interface name using type hinting. Do not need to define the class name for calling each and every class created in a file.
<?php
class
UserProfile {
private
$logger
;
public
function
createUser() {
echo
"creating user"
;
$this
->logger->log(
"User Created"
);
}
public
function
updateUser() {
echo
"updating user"
;
$this
->logger->log(
"User Updated"
);
}
public
function
deleteUser() {
echo
"deleting user"
;
$this
->logger->log(
"Deleting User"
);
}
public
function
__construct(LoggerInterface
$logger
)
{
$this
->logger =
$logger
;
}
}
?>
Now, create a file index.php
<?php
function
__autoload(
$class
) {
// classes is a directory where all
// the above files are placed.
include_once
"classes/$class.php"
;
}
function
getLogger(
$type
) {
switch
(
$type
) {
case
'email'
:
return
new
EmailLogger();
break
;
case
'database'
:
return
new
DBLogger();
break
;
case
'file'
:
return
new
FileLogger();
break
;
}
}
$logger
= getLogger(
'database'
);
$profile
=
new
UserProfile(
$logger
);
$profile
->createUser();
?>
Output:
Creating User. Logging message to DB: User Created
So, from this example create multiple files and define their functionality. All need to implement the interface class and just give the interface name in type hinting name as I have defined in UserProfile.php file.
- Traits: Traits was introduced in PHP5.4. It is the mechanism for code reuse in single inheritance language. The ‘trait’ keyword is used to define it.
Example:
<?php
class
abc {
public
function
test() {
echo
"test from class ABC"
;
}
}
trait
test {
public
function
test2() {
echo
"test2 method of test trait"
;
}
}
class
one
extends
abc {
use
test;
}
class
two
extends
abc {
use
test;
}
class
three
extends
abc {
}
class
four
extends
abc {
}
class
five
extends
abc {
}
$obj
=
new
one;
$obj
->test2();
?>
Output:test2 method of test trait
Here, taking a class abc and its functionality in all the child classes. So accessing the properties of abc class in all the child classes. Now consider a scenario where we need another function to be accessed only in class one and two but not in the rest of the classes. If you will define that function in the same class abc it will be available in all the classes which are extending class abc. So the solution is we can define that method in trait.
Trait is also similar to the classes. Here, define test2 function in trait test and use this trait by using ‘use’ keyword in child class. So we have used this trait only in class one and two because we need to access this method in class one and two. - Method Overriding in Traits: If defining the same method implemented in class and in trait also then preference will be given to the trait class method implementation. It means a trait class method will override the parent class method.
Example:
<?php
class
Base {
public
function
abc() {
echo
"ABC method from base class"
;
}
}
Trait Test {
public
function
abc() {
echo
"ABC method from test trait"
;
}
}
class
child
extends
Base {
use
Test;
}
$obj
=
new
Child;
$obj
->abc();
?>
Output:
ABC method from test trait
So, the order of preference is child class method > trait class method > parent class method.
- Access level in traits: You can change the access level of traits in child class.
Example:
<?php
trait
abc {
public
function
xyz() {
echo
"xyz method from trait abc"
;
}
}
class
test {
use
abc {
abc::xyz
as
public
abcXyz;
}
}
$obj
=
new
test;
$obj
->abcXyz();
?>
Output:xyz method from trait abc
- Namespaces: In PHP, class can not be redeclare. It means a class can not be declared more than once. It will display an error message. To solve this problem the concept of a namespace is used.
Example:
<?php
namespace
def {
class
xyz {
public
function
__construct() {
echo
"XYZ from DEF namespace"
;
}
}
}
namespace
{
class
xyz {
public
function
__construct() {
echo
"XYZ from Global namespace"
;
}
}
$obj
=
new
def/xyz();
}
?>
Output:
XYZ from DEF namespace
By default, all the classes are part of the global namespace. The global namespace declared with only keyword ‘namespace’ (no need to define the name of the namespace). The code can not be declared outside the namespace. Also, namespace should be the first line in your code if you are declaring a class in it.
There is alternate way as well to call the function from def class. just replace the code like below when you create an object.use def\xyz as def; $obj = new def();
The output will be the same. You can also make sub-namespace for a namespace. All you just need to do when you declare it is below the line.
namespace def\ghi
- Type Hinting: In PHP, don’t need to define the data type of variable you are declaring. It automatically defines the data type when creating a variable, but sometimes when you receive a variable, there you need to define what kind of variable you are receiving.
Example:
<?php
// Function definition
function
test(
array
$arr
) {
foreach
(
$arr
as
$k
=>
$v
) {
echo
$k
.
" "
.
$v
.
"\n"
;
}
}
// Declare an array
$array
= [
'abc'
=>
'ABC'
,
'xyz'
=>
'XYZ'
];
// Function call
test(
$array
);
?>
Output:abc ABC
xyz XYZSo, when receiving the variable and defined that it should be an array type. If you will parse string type data $array =’abcdefgh’ then you will get a fatal error and the code won’t execute. You can also do type hinting for class name and interface.