Object-Oriented Programming #
Introduction to Object-Oriented Programming (OOP) #
Definition of OOP #
Object-Oriented Programming (OOP) is an essential concept in computer programming. In technical jargon, OOP is said to be a paradigm, that is, an approach, a method.
Objectives and Advantages #
The purpose of OOP is to define and make “objects” interact with each other to facilitate code writing and maintenance.
Basic Elements of OOP #
Class #
A class is a plan or model that allows you to create objects. It contains attributes (which represent the data) and methods (which define the behaviors). A class is reusable and facilitates code standardization in a programming project.
Object #
An object represents a concept, an idea, or any entity from the physical world.
Examples: a car, a person, a page of a book…
The object has internally a structure and a behavior, and it knows how to interact with its peers.
Constructor #
A constructor is a special method of a class, called automatically when an object is created. It allows you to define the initial values of attributes and returns nothing. For example, the constructor of a Car class can initialize the brand and model.
Methods, Functions and static
#
A method is a function internal to a class. It determines the behavior of an object and can return a value.
For example, the displayInfos() method of a Client object can display its name and address.
All methods are functions, but not all functions are methods.
| Criterion | Function | Method |
|---|---|---|
| Definition | Block of code that executes an action, often independent | Function associated with a class or object |
| Ownership | Does not necessarily belong to a class | Belongs to a class (or an object) |
| Calling | Can be called alone, directly by its name (depending on the language) | Requires an object or the class to be called |
| Main Use | Perform general processing, often reusable everywhere | Describe a behavior or action specific to an object |
| Access to Attributes | Does not have access to an object’s attributes (unless passed as parameter) | Can access the object’s attributes via this (or self in Python) |
| Type | Rather a “general” concept | Specific to OOP (Object-Oriented Programming) |
A static method belongs to the class and doesn’t need an object to be called.
This facilitates:
-
Utility methods
-
Creation of small generic libraries
Example:
Math.sqrt(16); // static method, usage without instance
Major Principles of OOP #
Encapsulation #
Encapsulation consists of controlling access to members of a class (attributes and methods). A private attribute is only accessible within the class, a protected member within the class and its subclasses, and a public member is accessible everywhere. This principle protects the data and guarantees better code security.
| Modifier | Accessible in Class | Subclasses | Outside |
|---|---|---|---|
| private | Yes | No | No |
| protected | Yes | Yes | No |
| public | Yes | Yes | Yes |
Example:
// Attributes with different visibility levels
public name: string; // Accessible everywhere
protected age: number; // Accessible in class + child classes
private password: string; // Accessible only in this class
Inheritance #
Inheritance allows a class to inherit attributes and methods from another class, called the parent class. Thus, the child class can reuse existing code and specialize its behavior. The final keyword prevents a class from being inherited.
Example:
import { Person } from "./person";
export class Student extends Person {
public sayHello(): void {
throw new Error("Method not implemented.");
}
}
Polymorphism #
Polymorphism allows you to use methods with the same name, but with different behaviors depending on:
-
The type of the object (overriding).
-
The signature of the method (overloading).
Example:
class Animal {
makeSound(): void {
console.log("The animal makes a sound.");
}
}
class Dog extends Animal {
makeSound(): void {
console.log("The dog barks: Woof!");
}
}
class Cat extends Animal {
makeSound(): void {
console.log("The cat meows: Meow!");
}
}
const animals: Animal[] = [new Dog(), new Cat()];
animals.forEach(a => a.makeSound());
// Woof!
// Meow!
Abstraction #
Interfaces and Abstract Classes #
Interface #
An interface defines a set of methods common to multiple classes, without implementing them. It serves as a contract between classes and promotes standardization and modularity.
For example, the NameStrategy interface can impose the transform() method on multiple classes.
import { Person } from "./../person";
export interface NameStrategy {
/**
* Transform some string into others
* @param person: Person
* @returns string
*/
transform(person: Person): string
}
To implement an interface to a class, the code is as follows:
import type { Person } from "../person";
import type { NameStrategy } from "./name-strategy";
export class NameFirstStrategy implements NameStrategy {
transform(person: Person): string {
return person.getName() + ' ' + person.getFirstname()
}
}
Generic Types Associated with an Interface #
The generic parameter <T> indicates that any type can be accepted.
It allows you to make an interface or class flexible and reusable, without imposing a fixed type in advance.
Objective:
-
Adapt the code to different types
-
Guarantee consistency of the contract between classes
A generic interface, like IBuilder<T>, does not contain executed code but defines a contract that classes must follow.
Example of a generic interface:
public interface IBuilder<T> {
T build();
}
This interface only imposes:
-
A
build()method -
Which returns an object of the generic type
<T>
When a class implements the generic interface, it specifies the concrete type.
Example:
PersonBuilder<Person> → here, T = Person
What this implies:
-
The class must obligatorily implement
build() -
It can be abstract to serve as a base for other classes
-
The interface remains without code, only structural
Best practices for interfaces:
-
Prefer multiple small coherent interfaces rather than a single one with too many methods
-
One interface = one contract
-
An abstract class can have attributes and code, unlike an interface
Abstract Class #
An abstract class is a non-instantiable class, serving as a model for other classes. It can contain both implemented methods and abstract methods (without body). It provides a common base for multiple derived classes.
Example:
export abstract class Person {
protected name: string = '';
protected firstname: string = '';
protected email: string = '';
protected phone: string = '';
public birthdate: Date = new Date();
public gender: string = '';
constructor() {}
public abstract sayHello(): void;
}
Difference Between Abstract Class and Interface #
| Aspect | Abstract Class | Interface |
|---|---|---|
| Content | Methods with or without body | Methods without body only |
| Inheritance | Only one abstract class per class | Multiple interfaces possible |
| Usage | Serves as common base with partial behaviors | Serves as contract between classes |
SOLID Principles #
In object-oriented programming, SOLID is a mnemonic acronym that groups five design principles intended to produce more understandable, flexible, and maintainable software architectures.
S — Single Responsibility Principle
→ A class should have only one responsibility.
O — Open/Closed Principle
→ A class should be open for extension but closed for modification.
L — Liskov Substitution Principle
→ A subclass should be able to replace its parent class without altering the program’s behavior.
Example: a Square inherits from a Rectangle, but must guarantee that width = length.
I — Interface Segregation Principle
→ It is better to have multiple small interfaces than a single heavy interface.
D — Dependency Inversion Principle
→ High-level modules should not depend on low-level modules, but on abstractions.