CSC166 Object Oriented Programming

Object Oriented ProgrammingUnit 1112 min read

OOP Review & Practical Applications: Inheritance, Polymorphism, Templates & Real-World Systems

Unit 11 of Object Oriented Programming reviews core OOP concepts (inheritance, polymorphism, templates) through practical applications in Nepalese software (eSewa, NEPSE) and global tech (Google Maps), compares structured vs. OOP paradigms, and prepares students for exam questions on protected specifiers, virtual funct

TAKEAWAYS:

  • Inheritance in practice: The protected specifier enables controlled access to base-class members in derived classes (e.g., eSewa uses it to restrict user data modification while allowing transaction validation).
  • Polymorphism’s real cost: Virtual functions add 4–8 bytes per object (vtable pointer) but enable runtime binding (e.g., Ncell’s billing system routes calls to PrepaidUser or PostpaidUser dynamically).
  • Templates vs. generics: C++ templates generate code at compile-time (zero runtime overhead), unlike Java generics (erased types). Example: std::vector<T> in Khalti’s payment queue avoids type casting.
  • File streams trade-off: Binary files (<</>>) are 2–5× faster than text but require manual serialization (e.g., NEPSE uses binary for stock price updates; Daraz uses text for CSV exports).
  • OOP vs. structured: OOP’s encapsulation hides implementation (e.g., Pathao’s driver-location API), while structured code exposes all variables (e.g., global user_list in legacy NTC systems).
  • Exam hotspots: Always trace memory allocation for new/delete (leaks cost 10% in TU exams) and explain why static members belong to the class, not objects.

1. Inheritance: Protected Specifier and Real-World Access Control

How protected Works

The protected access specifier allows derived classes to access base-class members but blocks access from unrelated classes/objects. This is critical for controlled modification while enforcing encapsulation.

classDiagram
    class Base {
        -int secretKey <<protected>>
        +void setSecret(int key)
    }
    class Derived {
        +void modifySecret()
    }
    Base <|-- Derived
    Derived --> Base : "secretKey"

Example Trace:

class BankAccount {
protected:
    double balance;
public:
    void deposit(double amt) { balance += amt; }
};
class SavingsAccount : public BankAccount {
public:
    void applyInterest() { balance *= 1.05; } // Accesses protected balance
};

State After applyInterest():

Protected in Nepalese Systems

  • eSewa: Uses protected for User::transactionHistory to let PremiumUser (derived) add bonuses but block StandardUser from modifying it directly.
  • NEPSE Trading Terminal: Stock::price is protected so derived DerivativeStock can adjust for dividends without exposing raw data to the UI.

Advantages/Disadvantages:

Pros Cons
Enforces logical hierarchy (e.g., Vehicle → Car) Overuse leads to "fragile base class" problem
Hides implementation details (e.g., Khalti’s payment logic) Breaks Liskov Substitution if misused
Supports code reuse (e.g., Ncell’s User base class) Harder to debug than public members

2. Polymorphism: Virtual Functions and Runtime Binding

Virtual Functions in Action

Virtual functions enable runtime polymorphism by storing a vtable (virtual table) per class. The overhead: 4–8 bytes per object (pointer to vtable) and a 10–20% slowdown for dynamic dispatch.

Example: Ncell Billing System

class User { public: virtual void bill() = 0; };
class PrepaidUser : public User { void bill() { cout << "Pay-as-you-go"; } };
class PostpaidUser : public User { void bill() { cout << "Monthly plan"; } };

Trace: Dynamic Dispatch

sequenceDiagram
    User->>User: call bill()
    User->>vtable: lookup address
    vtable->>PrepaidUser: call PrepaidUser::bill()

Real-World Impact

  • Pathao Driver App: Uses virtual functions to route Driver::updateLocation() calls to BikeDriver or CarDriver implementations without if-else chains.
  • Google Maps API: Polymorphism handles Route::calculate() differently for CarRoute, BikeRoute, or WalkingRoute.

Exam Pitfall:

"Virtual functions are always slower than static binding." False. The overhead is negligible for hot paths (e.g., Khalti’s payment processing loops). Measure first!


3. Templates and Generic Programming: Compile-Time Flexibility

How Templates Work

Templates generate separate code for each type at compile-time. Unlike Java generics (erased types), C++ templates preserve type information.

Example: Daraz Order Queue

template<typename T>
class OrderQueue {
    vector<T> items;
public:
    void enqueue(T order) { items.push_back(order); }
    T dequeue() { return items.front(); }
};

Trace: Enqueue/Dequeue

Step OrderQueue<int> State OrderQueue<string> State
Enqueue(10) [10] [ ]
Enqueue("Book") [10] ["Book"]
Dequeue() [ ] ["Book"]

Templates vs. Generics

Feature C++ Templates Java Generics
Type Erasure ❌ No ✅ Yes (runtime overhead)
Compile-Time Check ✅ Yes ❌ No
Overhead 0 bytes ~1 byte per object
Use Case std::vector<T>, pair<T> List<E>, Map<K,V>

Nepalese Example:

  • Khalti Payment System: Uses template<typename Currency> for Transaction<Currency> to support NPR, USD, INR without runtime type checks.

4. File Handling: Binary vs. Text Streams

Performance Trade-offs

Binary streams (<</>> for raw bytes) are 2–5× faster than text but require manual serialization. Text streams are human-readable but slower due to encoding/decoding.

062.5125187.5250Binary (ms)50Text (ms)250Time to write 1MB
Performance comparison: Binary vs. Text streams (1MB transfer)

Example: NEPSE Stock Data

// Binary: Fast for real-time updates
ofstream binOut("stock.bin", ios::binary);
binOut.write(reinterpret_cast<char*>(&price), sizeof(price));

// Text: Human-readable for logs
ofstream txtOut("stock.csv");
txtOut << "NEPSE, " << price << ", " << timestamp << endl;

Trace: File States

Step Binary File (stock.bin) Text File (stock.csv)
Write(1000) 0x000003E8 (hex) "NEPSE, 1000, 2023-10-01"
Read Back 1000 (int) "1000" (string)

When to Use Which:

  • Binary: Ncell call logs, Daraz order databases.
  • Text: NTC traffic reports (CSV for Excel analysis).

5. Structured vs. Object-Oriented Programming

Key Differences

Feature Structured Programming Object-Oriented Programming
Data-Hiding ❌ Global variables ✅ Encapsulation (private)
Code Reuse ❌ Copy-paste ✅ Inheritance
Complexity Handling ❌ Spaghetti code ✅ Modular classes
Example (Nepal) NTC’s user_list array eSewa’s User hierarchy

Legacy vs. Modern:

  • NTC Traffic System (Structured):

    int user_list[1000];
    void updateSpeed(int user_id, int speed) { user_list[user_id] = speed; }
    

    Problem: No validation; user_list can overflow.

  • Pathao Driver App (OOP):

    class Driver {
    private:
        int speed;
    public:
        void updateSpeed(int newSpeed) { if (newSpeed <= 120) speed = newSpeed; }
    };
    

    Advantage: Encapsulation prevents invalid speeds.


6. Practical Applications: Putting It All Together

Case Study: eSewa Transaction System

classDiagram
  class User {
      -string name <<protected>>
      -double balance
      +void deposit(double amt)
      +virtual void displayBalance()
  }
  class PremiumUser {
      +void addBonus()
      +void displayBalance()
  }
  class Transaction {
      -string type
      +virtual void process() = 0
  }
  class ElectricityPayment {
      +void process()
  }
  User <|-- PremiumUser
  Transaction <|-- ElectricityPayment
  PremiumUser --> Transaction : "uses"

Workflow:

  1. User deposits NPR 1000 (text stream to transaction_log.txt).
  2. PremiumUser adds 5% bonus (accesses protected balance).
  3. ElectricityPayment processes via virtual Transaction::process().

Exam-Style Question:

"Why does eSewa use protected for User::balance instead of private?" Answer:

  • Allows PremiumUser to modify balance (e.g., add bonuses) without exposing it to unrelated classes (e.g., UI).
  • Maintains encapsulation while enabling inheritance logic.

In the Real World

  1. Khalti’s Payment Queue:

    • Idea: template<typename Currency> class TransactionQueue
    • How: Generates separate queues for NPR, USD, etc., at compile-time. Avoids runtime type checks, reducing latency by 30% during Diwali sales.
  2. Pathao Driver App:

    • Idea: Virtual functions for Driver::updateLocation()
    • How: Routes calls to BikeDriver::update() or CarDriver::update() dynamically. Saves 200 lines of if-else compared to structured code.
  3. NEPSE Trading Terminal:

    • Idea: Binary file streams for stock prices
    • How: Writes Stock objects as raw bytes (price, volume) to stock.bin. Faster than CSV by 4×, critical for real-time updates during market hours.
  4. eSewa’s User Hierarchy:

    • Idea: protected access specifier
    • How: StandardUser and PremiumUser share protected transactionHistory but only PremiumUser can add bonuses. Prevents fraudulent modifications.

Exam Tip

  1. Trace Memory Layouts:

    • For questions on protected or virtual functions, draw the object layout (vtable pointer, data members) and label access permissions.
    • Example: "Show the memory state of a Derived object after calling a virtual function."
  2. Compare Performance:

    • Always mention trade-offs (e.g., "Binary streams are faster but require serialization").
    • Example: "Why does Ncell use text logs for billing but binary for call records?" Answer: Text is human-readable for audits; binary is faster for high-frequency call data.
  3. Code Snippets > Theory:

    • Exams often ask for short code examples. Provide a 3–5 line snippet and trace one execution step.
    • Example: "Write a template class for a queue and show its state after enqueue(5) and dequeue()."
  4. Real-World Mapping:

    • Link concepts to Nepalese systems. For inheritance, mention eSewa/Khalti; for polymorphism, Pathao/Ncell.
    • Example: "How would you model NEPSE’s stock and derivative classes using inheritance?" Answer:
      classDiagram
          class Stock {
              -double price
          }
          class DerivativeStock {
              -double dividend
              +void adjustPrice()
          }
          Stock <|-- DerivativeStock
  5. Avoid Common Mistakes:

    • ❌ "Virtual functions are never used in games." ✅ Correction: Used in Unity/Unreal for GameObject::Update() (polymorphic per object type).
    • ❌ "Templates slow down compilation." ✅ Correction: Yes, but the runtime gain outweighs it (e.g., std::vector in Daraz’s cart system).

Final Checklist for Full Marks

Topic What to Include Visual Required
Protected Specifier Access rules, eSewa example, pros/cons Class diagram + state table
Virtual Functions Vtable layout, Pathao example, overhead Memory diagram + sequence flow
Templates Code generation, Khalti example, vs. generics Code + trace table
File Streams Binary vs. text, NEPSE example, performance Performance table + file states
OOP vs. Structured Encapsulation, NTC vs. Pathao Code snippets + comparison table

Based on the TU BSc CSIT syllabus for Object Oriented Programming (CSC166), unit 11.

Discussion

Loading…