CSS Prepare

optional · CSS study notes

Core OOP Concepts (extended)

  • Data Abstraction: exposing only essential features of an object while hiding implementation detail ("what it does," not "how it does it")
  • Encapsulation: bundling data (attributes) and methods (behavior) into a single unit (class), typically restricting direct access to internal state via access modifiers (private, protected, public)
  • Inheritance: a mechanism where a new class (derived/child) acquires properties and behavior of an existing class (base/parent), enabling code reuse and hierarchical classification
  • Polymorphism: "many forms" — the ability of different objects/classes to respond to the same interface/message in type-specific ways; achieved via function overloading (compile-time) and virtual functions (runtime)

C++ Example — One Per Pillar

Abstraction — hide implementation, expose only what's needed:

class BankAccount
{
private:
    double balance;   // hidden -- implementation detail

public:
    void   deposit(double amt) { balance += amt; }
    double getBalance()  const { return balance; }
};

Encapsulation — bundle data + methods, control access:

class Employee
{
private:
    double salary;   // hidden data

public:
    void   setSalary(double s) { if (s > 0) salary = s; }   // controlled write
    double getSalary()   const { return salary; }
};

Inheritance — reuse a base class's members:

class Animal
{
public:
    void eat() { cout << "Eating...\n"; }
};

class Dog : public Animal   // Dog "is-a" Animal
{
public:
    void bark() { cout << "Barking...\n"; }
};

// Dog d; d.eat(); d.bark();  -- eat() is reused, not rewritten

Polymorphism — same interface, different behavior:

class Printer
{
public:
    void print(int i)    { cout << "int: "    << i << "\n"; }
    void print(double d) { cout << "double: " << d << "\n"; }
};

// Same function name "print" behaves differently per argument type --
// compile-time polymorphism (function overloading). Runtime
// polymorphism via virtual functions is covered on the dedicated page.

Also Frequently Tested

  • Message passing: objects communicate by invoking each other's member functions — calling obj.method(args) is "sending obj a message"; sometimes listed as a supporting OOP feature alongside the four core pillars
  • Benefits of OOP (common short-answer question): code reusability (inheritance), data security (encapsulation), reduced complexity (abstraction), flexibility/extensibility (polymorphism), easier maintenance

MCQ Trap

  • Encapsulation and Data Abstraction are related but distinct: abstraction is about hiding complexity/showing only essentials; encapsulation is the mechanism (bundling + access control) that achieves it.
  • Message passing isn't unique to OOP — what makes it distinctly OOP is that the message is sent to an object, which itself decides how to respond (ties directly into polymorphism)

Main Characteristic of Object-Oriented Paradigm (procedural vs OOP)

AspectProcedural (e.g. C)Object-Oriented (e.g. C++)
Organizing unitFunctionsObjects (data + functions bundled together)
Data & function relationshipSeparate — data passed between free-standing functionsCoupled — data and the functions that operate on it live inside one class
Data securityGlobal data freely accessible, error-proneAccess control via private/protected/public
Code reuseCopy-paste or function reuseInheritance — extend existing classes without rewriting
Real-world modelingStep-by-step proceduresEntities/objects, closer to how real systems are structured

The defining characteristic examiners look for: OOP models a system as a set of interacting objects, each bundling its own data and behavior, rather than as a sequence of procedures acting on shared data — this single shift is what enables encapsulation, inheritance, and polymorphism to work together.

Quick illustration — all four pillars in one class

#include <iostream>
using namespace std;

class Account               // Encapsulation: data + behavior bundled together
{
private:
    double balance;          // hidden — Abstraction: user doesn't need to know internal representation

public:
    Account(double initial) : balance(initial) {}   // Constructor

    void deposit(double amt) { balance += amt; }     // controlled access, not direct field manipulation
    double getBalance() const { return balance; }
};

class SavingsAccount : public Account    // Inheritance: reuses Account's behavior
{
public:
    SavingsAccount(double initial) : Account(initial) {}
    void addInterest() { deposit(getBalance() * 0.05); }   // extends behavior
};

Polymorphism isn't shown here (needs virtual — see the Polymorphism page) but this snippet demonstrates encapsulation, abstraction, and inheritance working together in a single realistic example.

Self-Test Questions

  1. What is the single defining shift that separates OOP from procedural programming?
  2. Give one advantage of bundling data and functions into a class instead of keeping them separate.