Published in Mar 11, 2024
•
Imagine building with Legos instead of individual bricks. This is similar to Object-Oriented Programming (OOP) in coding. We create mini-programs called "objects" that act like reusable building blocks.
Car object. It might have data like color and model, and functions like accelerate() and brake().Benefits of using objects:
OOP is like a powerful toolbox for building programs. It helps us write cleaner, more efficient, and easier-to-maintain code.

study() function.Teacher class might inherit from Person and a GraduateStudent class might inherit from Student. This way, each class inherits the features of the class above it.Car class might have a start() function, but you wouldn't need to know how the engine actually starts (by key or button).Essentially, these features are like tools in your OOP toolbox:

Object-Oriented Programming (OOP) is a programming paradigm in computer science that relies on the concept of classes and objects. It is used to structure a software program into simple, reusable pieces of code blueprints (usually called classes), which are used to create individual instances of objects. There are many object-oriented programming languages, including JavaScript, TypeScript, Java and PHP.
OOP languages are not necessarily restricted to the object-oriented programming paradigm. Some languages, such as JavaScript, Python and PHP, all allow for both procedural and object-oriented programming styles.
A class is an abstract blueprint that creates more specific, concrete objects. Classes often represent broad categories, like Car or Dog that share attributes. These classes define what attributes an instance of this type will have, like color, but not the value of those attributes for a specific object.
Classes can also contain functions called methods that are available only to objects of that type. These functions are defined within the class and perform some action helpful to that specific object type. For example, our Car class may have a repaint method that changes the color attribute of our car. This function is only helpful to objects of type Car, so we declare it within the Car class, thus making it a method.
Class templates are used as a blueprint to create individual objects. These represent specific examples of the abstract class, like myCar or goldenRetriever. Each object can have unique values to the properties defined in the class. For example, say we created a class, Car, to contain all the properties a car must have, color, brand, and model. We then create an instance of a Car type object, myCar to represent my specific car.

Let’s take a real-world problem and conceptually design an OOP software program.
Imagine running a convention where you keep track of the names, ages, days attended for each attendee. How would you design simple, reusable software to model each attendee?
With hundred of attendees, it would be highly inefficient to write unique entries for each one because a lot of redundant code would be written. Check out what this might look like with objects Juan and Agustina .
<?php
// Define class Attendee
class Attendee {
public $name;
public $birthday;
public $daysAttended = 0;
// Constructor to set initial values
public function __construct(string $name, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
// Method to calculate age
public function getAge(): int {
$now = new DateTime();
$interval = $now->diff($this->birthday);
return $interval->y;
}
}
// Create objects for Juan and Agustina
$juan = new Attendee("Juan", "14/01/1994");
$agustina = new Attendee("Agustina", "01/12/1996");
// Access properties and methods
echo "Juan's age: " . $juan->getAge() . " years old\n";
echo "Juan's attendance: " . $juan->attendance . "\n";
echo "Agustina's age: " . $agustina->getAge() . " years old\n";
echo "Agustina's attendance: " . $agustina->attendance . "\n";// Interface for Attendee information
interface Attendee {
name: string;
birthday: string;
age(): number;
daysAttended: number;
}
// Object of one individual attendee
const juan: Attendee = {
name: "Juan",
birthday: "14/01/1994",
age(): number {
return Date.now() - new Date(this.birthday).getTime();
},
daysAttended: 0,
};
// Object of second individual attendee
const agustina: Attendee = {
name: "Agustina",
birthday: "01/12/1996",
age(): number {
return Date.now() - new Date(this.birthday).getTime();
},
daysAttended: 0,
};As you can see, there is a lot of duplicated code between both objects. The age() function appears in each object. Since we want the same information for each attendee, we can use objects and classes instead. Grouping related information together to form a class structure makes the code shorter and easier to maintain.
In the convention example, here’s how a programmer could think about organizing an OOP:
The diagram below represents how to design an OOP program by grouping the related data and behaviors together to form a simple template and then creating subgroups for specialized data and behavior.
The Attendee class is a generic template containing only the structure of data and behaviors common to all attendees as attributes.
We then create two child classes of Attendee, Seller and Speaker. These have the inherited behaviors of Attendee (getAge()) but also behavior unique to attendees of that subtype.
Finally, we create objects of the Speaker type to represent the individual dogs Juan and Agustina.

There’s four fundamental building blocks of and OOP algorithm that were used above:
Classes are essentially user-defined data types. Here is where we create a blueprint for the structure of methods and attributes. Individual objects are instantiated from this blueprint.
They contain fields for attributes and methods for behaviors. In out Attendee class example, attributes include name and birthday, while methods include getAge() and updateAttendance().
Here are some snippets in PHP and TypeScript
// Define class Attendee
class Attendee {
private $name;
private $birthday;
private $daysAttended = 0;
// Constructor to set initial values
public function __construct(string $name, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
// Method to calculate age
public function getAge(): int {
$now = new DateTime();
$interval = $now->diff($this->birthday);
return $interval->y;
}
// Method to update attendance
public function updateAttendance(): void {
$this->daysAttended++;
}
}class Attendee {
constructor(name: string, birthday: Date) { // Specify types for parameters
this.name = name;
this.birthday = birthday;
}
private _daysAttended = 0: number; // Declare private variable with type
getAge(): number { // Specify return type of getter
return this.calcAge();
}
private calcAge(): number { // Mark function as private
return Date.now() - this.birthday;
}
getAge(): void { // Specify function doesn't return anything (void)
return Date.now() - new Date(this.birthday).getTime();
}
updateAttendance(): void { // Specify function doesn't return anything
this._daysAttended++;
}
}Objects are instances of a class created with specific data. For example, in the code snippet below, Juan is an instance of the Attendee class.
// Define class Attendee
class Attendee {
private $name;
private $birthday;
private $daysAttended = 0;
// Constructor to set initial values
public function __construct(string $name, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
// Method to calculate age
public function getAge(): int {
$now = new DateTime();
$interval = $now->diff($this->birthday);
return $interval->y;
}
// Method to update attendance
public function updateAttendance(): void {
$this->daysAttended++;
}
}
$juan = new Attendee("Juan", "14/01/1994");class Attendee {
constructor(name: string, birthday: Date) { // Specify types for parameters
this.name = name;
this.birthday = birthday;
}
private _daysAttended = 0: number; // Declare private variable with type
getAge(): number { // Specify return type of getter
return this.calcAge();
}
private calcAge(): number { // Mark function as private
return Date.now() - this.birthday;
}
getAge(): void { // Specify function doesn't return anything (void)
return Date.now() - new Date(this.birthday).getTime();
}
updateAttendance(): void { // Specify function doesn't return anything
this._daysAttended++;
}
}
const juan = new Attendee("Juan", "14/01/1994");When the new class Attendee is called:
juanname & birthday arguments, and assigns valuesAttributes are the information that is stored. Attributes are defined in the Class template. When objects are instantiated, individual objects contain data stored in the Attributes field. The state of an object is defined by the data in the object’s attributes fields.
Methods represent behaviors. Methods perform actions; methods might return information about an object or update an object’s data. The method’s code is defined in the class definition.
When individual objects are instantiated, these objects can call the methods defined in the class. In the code snippet below, the getAge() method is defined in the Attendee class, and the getAge() method is called on the Speaker object.
Methods often modify, update or delete data. Methods don’t have to update data though. For example, the getAge() method doesn’t update any data because barking doesn’t modify any of the attributes of the Attendee class: name or birthday. The updateAttendance() method adds a day the Attendee attended the pet-sitting camp. The attendance attribute is important to keep track of for billing Owners at the end of the month.
Methods are how programmers promote reusability and keep functionality encapsulated inside an object. This reusability is a great benefit when debugging. If there’s an error, there’s only one place to find it and fix it instead of many.
The underscore in _daysAttended or private in private $daysAttended denotes that the variable is protected and shouldn’t be modified directly. The updateAttendance() method changes _daysAttended or $daysAttended.
The four pillars of object-oriented programming are:
Inheritance allows classes to inherit features of other classes. Put another way, parent classes extend attributes and behaviors to child classes. Inheritance supports reusability. If basic attributes and behaviors are defined in a parent class, child classes can be created, extending the functionality of the parent class and adding additional attributes and behaviors. For example, speaker have the unique role to be as such. In other words, all speakers are attendees, but not all attendees are speakers.
We represent this difference by creating a child class SpeakerAttendee from the parent class Attendee, and then adding the unique getOnStage() behavior.
The benefits of inheritance are programs can create a generic parent class and then create more specific child classes as needed. This simplifies programming because instead of recreating the structure of the Attendee class multiple times, child classes automatically gain access to functionalities within their parent class. In the following code snippet, child class SpeakerAttendee inherits the method getAge() from the parent class Attendee, and the child class adds an additional method, getOnStage().
// Define class Attendee
class Attendee {
private $name;
private $birthday;
private $daysAttended = 0;
// Constructor to set initial values
public function __construct(string $name, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
// Method to calculate age
public function getAge(): int {
$now = new DateTime();
$interval = $now->diff($this->birthday);
return $interval->y;
}
// Method to update attendance
public function updateAttendance(): void {
$this->daysAttended++;
}
}
class SpeakerAttendee extends Attendee {
private $topic;
private $timeOnStage = 0;
// Constructor to set initial values
public function __construct(string $topic, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
public function getOnStage(): void {
return "Hello World!";
}
public function updateTimeOnStage(int minutes): void {
$this->timeOnStage = minutes;
}
}class Attendee {
constructor(name: string, birthday: Date) { // Specify types for parameters
this.name = name;
this.birthday = birthday;
}
private _daysAttended = 0: number; // Declare private variable with type
getAge(): number { // Specify return type of getter
return this.calcAge();
}
private calcAge(): number { // Mark function as private
return Date.now() - this.birthday;
}
getAge(): void { // Specify function doesn't return anything (void)
return Date.now() - new Date(this.birthday).getTime();
}
updateAttendance(): void { // Specify function doesn't return anything
this._daysAttended++;
}
}
class SpeakerAttendee extends Attendee {
constructor(topic: string, timeOnStage: number) { // Specify types for parameters
this.topic = topic;
this.timeOnStage = timeOnStage;
}
getOnStage(): void {
return console.log("Hello World!");
}
updateTimeOnStage(minutes: number): void {
this.timeOnStage = minutes;
}
}Notice that the SpeakerAttendee class does not have a copy of the getAge() method. It inherits this method defined in the parent Attendee class. When the code calls juan.getAge() method, the method walks up the chain of child to parent classes to find where the it’s defined.
// Define class Attendee
class Attendee {
private $name;
private $birthday;
private $daysAttended = 0;
// Constructor to set initial values
public function __construct(string $name, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
// Method to calculate age
public function getAge(): int {
$now = new DateTime();
$interval = $now->diff($this->birthday);
return $interval->y;
}
// Method to update attendance
public function updateAttendance(): void {
$this->daysAttended++;
}
}
class SpeakerAttendee extends Attendee {
private $topic;
private $timeOnStage = 0;
// Constructor to set initial values
public function __construct(string $topic, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
public function getOnStage(): void {
return "Hello World!";
}
public function updateTimeOnStage(int minutes): void {
$this->timeOnStage = minutes;
}
}
$juan = new SpeakerAttendee("Juan", "14/01/1994");
echo $juan.getAge();class Attendee {
constructor(name: string, birthday: Date) { // Specify types for parameters
this.name = name;
this.birthday = birthday;
}
private _daysAttended = 0: number; // Declare private variable with type
getAge(): number { // Specify return type of getter
return this.calcAge();
}
private calcAge(): number { // Mark function as private
return Date.now() - this.birthday;
}
getAge(): void { // Specify function doesn't return anything (void)
return Date.now() - new Date(this.birthday).getTime();
}
updateAttendance(): void { // Specify function doesn't return anything
this._daysAttended++;
}
}
class SpeakerAttendee extends Attendee {
constructor(topic: string, timeOnStage: number) { // Specify types for parameters
this.topic = topic;
this.timeOnStage = timeOnStage;
}
getOnStage(): void {
return console.log("Hello World!");
}
updateTimeOnStage(minutes: number): void {
this.timeOnStage = minutes;
}
}
const juan = new SpeakerAttendee("Juan", "14/01/1994");
console.log(juan.getAge());In JavaScript / TypeScript, inheritance is also known as prototyping. A prototype object is a template for another object to inherit properties and behaviors. There can be multiple prototype object templates, creating a prototype chain.
This is the same concept as the parent/child inheritance. Inheritance is from parent to child. In our example, all three dogs can bark, but only Juan and Agustina can herd. The getOnStage() method is defined in the child SpeakerAttendee class, so the two objects, Juan and Agustina, instantiated from the SpeakerAttendee class have access to the getOnStage() method.
Encapsulation means containing all important information inside an object, and only exposing selected information to the outside world. Attributes and behaviors are defined by code inside the class template. Then, when an object is instantiated from the class, the data and methods are encapsulated in that object. Encapsulation hides the internal software code implementation inside a class and hides the internal data of inside objects.
Let’s use a car as a metaphor for encapsulation. The information the car shares with the outside world, using blinkers to indicate turns, are public interfaces. In contrast, the engine is hidden under the hood. It’s a private, internal interface. When you’re driving a car down the road, other drivers require information to make decisions, like whether you’re turning left or right. However, exposing internal, private data like the engine temperature would confuse other drivers.

Encapsulation adds security. Attributes and methods can be set to private, so they can’t be accessed outside the class. To get information about data in an object, public methods & properties are used to access or update data. This adds a layer of security where the developer chooses what data can be seen on an object by exposing that data through public methods in the class definition.
Within classes, most programming languages have public, protected, and private sections. The public section is the limited selection of methods accessible from the outside world or other classes within the program. Protected is only accessible to child classes. Private code can only be accessed from within that class.
Encapsulating & updating data: Since methods can also update an object’s data, the developer controls what values can be changed through public methods. This allows us to hide important information that should not be changed from phishing and the more likely scenario of other developers mistakenly changing important data.
Encapsulation adds security to code and makes it easier to collaborate with external developers. When you’re programming to share information with an external company, you wouldn’t want to expose the classes’ templates or private data because your company owns that intellectual property. Instead, developers create public methods that allow other developers to call methods on an object. Ideally, these public methods come with documentation for external developers.
Benefits of encapsulation:
Abstraction is an extension of encapsulation that uses classes and objects, which contain data and code, to hide the internal details of a program from its users. This is done by creating a layer of abstraction between the user and the more complex source code, which helps protect sensitive information stored within the source code.
Key points of abstraction:
Abstraction can also be explained using cars. Think of how a driver operates a vehicle using only the car’s dashboard. A driver uses the car’s steering wheel, accelerator, and brake pedals to control the vehicle. The driver does not have to worry about how the engine works or what parts are used for each movement. This is an abstraction – only the important aspects necessary for a driver to use the car are visible. Similarly, data abstraction allows developers to work with complex information without worrying about its inner workings. In this way, it helps to improve code quality and readability.

Abstraction also serves an important security role. By only displaying selected pieces of data and only allowing data to be accessed through classes and modified through methods, we protect the data from exposure. To continue with the car example, you wouldn’t want an open gas tank while driving a car.
The benefits of abstraction are summarized below:
Polymorphism means designing objects to share behaviors. Using inheritance, objects can override shared parent behaviors with specific child behaviors. Polymorphism allows the same method to execute different behaviors in two ways: method overriding and method overloading.
Runtime polymorphism uses method overriding. In method overriding, a child class can implement differently than its parent class. In our dog example, we may want to give SpeakerAttendee a specific method different than the generic Attendee class.
// Define class Attendee
class Attendee {
private $name;
private $birthday;
private $daysAttended = 0;
// Constructor to set initial values
public function __construct(string $name, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
// Method to calculate age
public function getAge(): int {
$now = new DateTime();
$interval = $now->diff($this->birthday);
return $interval->y;
}
// Method to update attendance
public function updateAttendance(): void {
$this->daysAttended++;
}
public function greet(): void {
return "Hi!";
}
}
class SpeakerAttendee extends Attendee {
private $topic;
private $timeOnStage = 0;
// Constructor to set initial values
public function __construct(string $topic, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
public function getOnStage(): void {
return "Hello World!";
}
public function updateTimeOnStage(int minutes): void {
$this->timeOnStage = minutes;
}
public function greet(): void {
return "Hello Everyone!";
}
}
$juan = new SpeakerAttendee("Juan", "14/01/1994");
echo $juan.greet(); // returns "Hello Everyone!"
Method Overloading Compile Time polymorphism uses method overloading. Methods or functions may have the same name but a different number of parameters passed into the method call. Different results may occur depending on the number of parameters passed in.
// Define class Attendee
class Attendee {
private $name;
private $birthday;
private $daysAttended = 0;
// Constructor to set initial values
public function __construct(string $name, string $birthday) {
$this->name = $name;
$this->birthday = new DateTime($birthday);
}
// Method to calculate age
public function getAge(): int {
$now = new DateTime();
$interval = $now->diff($this->birthday);
return $interval->y;
}
// Method to update attendance
public function updateAttendance(): void {
// add a day
$this->daysAttended++;
}
public function updateAttendance(int x): void {
// adds multiple days
$this->daysAttended += $this->daysAttended;
}
}
$juan = new Attendee("Juan", "14/01/1994");
$juan->updateAttendance(); // $daysAttended = 1;
$juan->updateAttendance(5); // $daysAttended = 6;The benefits of Polymorphism are:
Object-oriented programming requires thinking about the structure of the program and planning out an object-oriented design before you start coding. OOP in computer programming focuses on how to break up the requirements into simple, reusable classes that can be used to blueprint instances of objects. Overall, implementing OOP allows for better data structures and reusability, saving time in the long run.