JET Academy

What is Object-Oriented Programming?

Object-Oriented Programming (OOP) is one of the most widely used and influential paradigms of modern programming. This approach organizes software based on the principle of modeling real-world objects and their interactions. The OOP concept began to take shape in the 1960s and gained a dominant position in the programming world in the 1980s-1990s.

Core Philosophy and Ideology

At the center of object-oriented programming lies a way of thinking similar to the real world. In traditional procedural programming, a program was built as a collection of functions and procedures - that is, answering the question "what should be done." OOP asks a different question: "what objects exist and how do they interact with each other?" In this paradigm, a program is conceived as a system of objects interacting with one another.

For example, when modeling a banking system, the procedural approach would create functions like "transfer money," "check account," "calculate interest." In the OOP approach, objects like "Customer," "Account," "Transaction," "Card" are created, and each has its own data and behaviors. These objects represent corresponding elements in the real world, and natural relationships are established between them.

Four Fundamental Principles of OOP

Object-oriented programming is built on four fundamental principles: encapsulation, abstraction, inheritance, and polymorphism. Together, these principles enable the creation of powerful, flexible, and easily maintainable software.

1. Encapsulation

Encapsulation is the process of combining data and the methods that operate on that data within a single unified structure and protecting them from external interference. This principle is closely tied to the concept of "data hiding."

A simple real-world example: a television remote control. You control the television's operation by pressing buttons, but you don't need to know how it works inside. The internal mechanism of the remote is protected, and you interact with it only through an open interface (the buttons).

In programming, encapsulation is implemented through access modifiers: private, protected, public, and in some languages, internal. Private variables and methods are accessible only within their own class, while public elements can be used from anywhere. Protected elements are accessible within the inheritance chain.

Advantages of encapsulation:

  • Data security: External code cannot directly modify variables
  • Ease of changing internal implementation: You can update the internal mechanism without changing the external interface
  • Improved code quality: Logic is concentrated in one place
  • Reduced errors: Ensuring proper use of data

For example, when creating a bank account class, we make the balance variable private and provide getter and setter methods for accessing it:



class BankAccount {

private double balance;

public double getBalance() {

return balance;

}

public void deposit(double amount) {

if (amount > 0) {

balance += amount;

}

}

}

With this approach, it's impossible to directly assign a negative value to the balance, and all operations are under control.

2. Inheritance

Inheritance is a mechanism where one class (derived or child class) inherits the properties and behaviors of another class (base or parent class). This principle prevents code duplication and allows for hierarchical relationships between classes.

Real-world analogy: the principle of inheritance in biology. Children inherit genetic characteristics from their parents but also have their own unique characteristics.

In programming, inheritance expresses the "is-a" relationship. For example, "Dog is an Animal," "Square is a Shape," "Student is a Person" - such relationships are modeled through inheritance.

Example to be given: vehicle hierarchy. All vehicles have common characteristics: brand, model, year of manufacture, speed. A car may have additional characteristics: number of doors, fuel type. A motorcycle has different additional characteristics: type (sport, city, etc.), cylinder capacity.



class Vehicle {

protected String brand;

protected String model;

protected int yearOfManufacture;

public void move() {

// general movement logic

}

}


class Car extends Vehicle {

private int numberOfDoors;

private String fuelType;

public void park() {

// car-specific functionality

}

}


class Motorcycle extends Vehicle {

private String type;

private int cylinderCapacity;

public void wheelie() {

// motorcycle-specific functionality

}

}

Types of inheritance:

  • Single inheritance: A class can inherit from only one base class (Java, C#)
  • Multiple inheritance: A class can inherit from several base classes (C++, Python)
  • Multilevel inheritance: Class A inherits from B, class B inherits from C
  • Hierarchical inheritance: Several derived classes are created from one base class
  • Hybrid inheritance: A combination of the above

3. Polymorphism

Polymorphism means "many forms" in Greek and is the ability of the same interface or method to work differently in different contexts. This principle facilitates code flexibility and extensibility.

There are two main types of polymorphism:

Compile-time/Static polymorphism: Implemented through method overloading. Methods with the same name accept different parameters:



class Calculator {

public int add(int a, int b) {

return a + b;

}

public double add(double a, double b) {

return a + b;

}

public int add(int a, int b, int c) {

return a + b + c;

}

}

Runtime/Dynamic polymorphism: Implemented through method overriding. The derived class redefines the parent class's method:



class Animal {

public void makeSound() {

System.out.println("Animal makes a sound");

}

}


class Dog extends Animal {

@Override

public void makeSound() {

System.out.println("Woof-woof!");

}

}


class Cat extends Animal {

@Override

public void makeSound() {

System.out.println("Meow-meow!");

}

}

Polymorphism is particularly powerful because we can store and work with different derived class objects in a base class type:



Animal animal1 = new Dog();

Animal animal2 = new Cat();


animal1.makeSound(); // "Woof-woof!"

animal2.makeSound(); // "Meow-meow!"

4. Abstraction

Abstraction is the process of creating a simplified model of complex systems and hiding insignificant details while emphasizing essential characteristics. This principle allows users to work only with necessary information.

Real-world example: driving a car. The driver only interacts with the steering wheel, pedals, and gear shift. There's no need to know how the engine works or how fuel burns. The car's internal complexity is abstracted.

In programming, abstraction is implemented through two main mechanisms:

Abstract classes: Classes from which objects cannot be created, used only for inheritance. They can contain abstract methods (methods without implementation):



abstract class Shape {

protected String color;

// abstract method - no implementation

public abstract double calculateArea();

// concrete method

public void changeColor(String newColor) {

this.color = newColor;

}

}


class Circle extends Shape {

private double radius;

@Override

public double calculateArea() {

return Math.PI * radius * radius;

}

}


class Rectangle extends Shape {

private double length;

private double width;

@Override

public double calculateArea() {

return length * width;

}

}

Interfaces: Completely abstract structures that contain only method signatures (in modern languages, default implementations are also possible). A class can implement multiple interfaces:



interface Flyable {

void fly();

void land();

}


interface Swimmable {

void swim();

void dive();

}


class Duck implements Flyable, Swimmable {

public void fly() {

System.out.println("Duck is flying");

}

public void land() {

System.out.println("Duck is landing");

}

public void swim() {

System.out.println("Duck is swimming");

}

public void dive() {

System.out.println("Duck is diving");

}

}

Class and Object Concepts

The foundational building blocks of OOP are the concepts of class and object.

Class: A template or blueprint for objects. A class defines data fields (attributes/fields) and methods (functions), but is not yet a concrete instance. Real-world analogy: a house plan. The plan shows how houses should be built, but it is not a house itself.

Object: A concrete instance of a class. Each object has its own unique values but shares the structure and behaviors of the same class. In the real world: concrete houses built based on a plan. Each house is based on the same plan but can have a different address, color, and resident.



// Class definition

class Student {

// Fields (data)

private String firstName;

private String lastName;

private int age;

private double GPA;

// Constructor

public Student(String firstName, String lastName, int age) {

this.firstName = firstName;

this.lastName = lastName;

this.age = age;

this.GPA = 0.0;

}

// Methods (behaviors)

public void registerForCourse(String courseName) {

System.out.println(firstName + " registered for " + courseName);

}

public void takeExam(String course, double score) {

System.out.println(firstName + " scored " + score + " on " + course + " exam");

}

// Getters and Setters

public double getGPA() {

return GPA;

}

public void setGPA(double newGPA) {

if (newGPA >= 0 && newGPA <= 4.0) {

this.GPA = newGPA;

}

}

}


// Object creation

Student student1 = new Student("Aydin", "Mammadov", 20);

Student student2 = new Student("Leyla", "Hasanova", 19);


// Working with objects

student1.registerForCourse("Mathematics");

student1.setGPA(3.75);

student2.takeExam("Physics", 95);

Constructor and Destructor

Constructor: A special method that is automatically called when an object is created. The constructor's name is the same as the class name and has no return type. Constructors are used to set the initial state of the object.

Types of constructors:

  • Default constructor: A parameterless constructor
  • Parameterized constructor: A constructor that accepts parameters
  • Copy constructor: A constructor that creates a copy of another object
  • Constructor overloading: Multiple constructors with different parameters in the same class



class Book {

private String title;

private String author;

private int pageCount;

// Default constructor

public Book() {

this.title = "Unknown";

this.author = "Unknown";

this.pageCount = 0;

}

// Parameterized constructor

public Book(String title, String author) {

this.title = title;

this.author = author;

this.pageCount = 0;

}

// Fully parameterized constructor

public Book(String title, String author, int pageCount) {

this.title = title;

this.author = author;

this.pageCount = pageCount;

}

// Copy constructor

public Book(Book anotherBook) {

this.title = anotherBook.title;

this.author = anotherBook.author;

this.pageCount = anotherBook.pageCount;

}

}

Destructor: A method called before an object is deleted from memory. It exists explicitly in languages like C++, while in languages like Java and C#, the garbage collector performs automatic memory management.

Relationship Types

In OOP, there are various types of relationships between objects and classes:

1. Association: A general relationship between two classes. Can be thought of as a "uses-a" relationship. For example, the relationship between Teacher and Student - a teacher teaches a student.

2. Aggregation: A "has-a" relationship, but with weak dependency. One object contains another, but they can exist independently. For example, Department and Teacher - a department consists of teachers, but a teacher can exist without a department.

3. Composition: A strong "has-a" relationship. If the main object is destroyed, the constituent parts are also destroyed. For example, House and Room - if a house is destroyed, the rooms disappear too.

4. Inheritance: The "is-a" relationship already explained in detail above.

Advantages of OOP

  1. Modularity: Code is organized in small, manageable modules. Each class can function as an independent unit.
  2. Reusability: Through inheritance and composition, existing code can be used in new projects.
  3. Maintainability: Because code organization and structure are clear, making changes and finding errors becomes easier.
  4. Flexibility and Extensibility: Thanks to polymorphism and abstraction, it's easy to expand and modify the system.
  5. Real-world correspondence: Since OOP models real-world objects, understanding and designing complex systems becomes easier.
  6. Security: Encapsulation ensures data protection.
  7. Problem solving: Large problems can be divided into small, manageable parts.

Disadvantages of OOP

  1. Learning curve: Can be more difficult to learn compared to procedural programming.
  2. Performance: Abstraction and additional structures can sometimes cause performance loss.
  3. Design complexity: Creating proper class hierarchies and designs requires experience.
  4. Over-engineering: Sometimes overly complex solutions can be created for simple problems.
  5. Memory usage: Objects require additional metadata and structures.

Languages Supporting OOP

Different programming languages support OOP to varying degrees:

Pure OOP languages: Java, C#, Ruby, Smalltalk - in these languages, everything is an object.

Hybrid languages: C++, Python, JavaScript, PHP - support both OOP and other paradigms.

Languages with OOP elements: Visual Basic, Delphi, Objective-C.

Modern Trends and Development

In modern programming, OOP is not used alone but is combined with other paradigms:

  • Functional programming elements: Java 8+, C# LINQ
  • Aspect-oriented programming: For cross-cutting concerns
  • Reactive programming: For asynchronous data streams

Design Patterns

Proven solutions for frequently recurring problems in the OOP context:

  • Creational patterns: Singleton, Factory, Builder
  • Structural patterns: Adapter, Decorator, Facade
  • Behavioral patterns: Observer, Strategy, Command

Conclusion

Object-Oriented Programming is a powerful paradigm that forms the foundation of modern software. Four fundamental principles - encapsulation, inheritance, polymorphism, and abstraction - together enable the creation of modular, reusable, and easily maintainable code. The ability to model real-world objects simplifies the design of complex systems. While OOP is not perfect, it remains a dominant and effective approach in enterprise-level applications, game development, mobile programming, and many other fields.

Register to Learn More About Our Courses

Tags:

Other Course Fields