#include <iostream>
using namespace std;
// ============================================================================
// OOP CONCEPT: CLASS & OBJECT
// Class: A blueprint defining state (attributes) and behavior (functions).
//
// OOP PILLAR 1: ENCAPSULATION
// Bundles data members and functions operating on them inside a single unit.
// ============================================================================
class Pizza {
// ------------------------------------------------------------------------
// OOP CONCEPT: DATA HIDING (Access Specifier: private)
// Internal state is hidden from outside modification to enforce business rules.
// ------------------------------------------------------------------------
private:
int basePri = 250;
int nonBasePr = 400;
int cheese = 50;
int ncheese = 70;
int topping = 80;
int ntopping = 100;
// Internal state flags (Encapsulated validation)
bool isCheese = false;
bool isTop = false;
// ------------------------------------------------------------------------
// OOP CONCEPT: ACCESS CONTROL (Access Specifier: protected)
// Accessible only within this class and derived subclasses (Deluxe).
// ------------------------------------------------------------------------
protected:
bool isVeg;
int total = 0;
// ------------------------------------------------------------------------
// OOP PILLAR 2: ABSTRACTION (Access Specifier: public)
// Exposes essential actions while hiding implementation and calculation details.
// ------------------------------------------------------------------------
public:
// --------------------------------------------------------------------
// OOP CONCEPT: CONSTRUCTOR & 'this' POINTER
// Invoked at object creation. 'this' refers to the current invoking instance.
// --------------------------------------------------------------------
Pizza(bool isVeg) {
this->isVeg = isVeg;
Base();
}
// OOP CONCEPT: VIRTUAL DESTRUCTOR
// Essential in base classes to prevent undefined behavior when deleting via base pointer.
virtual ~Pizza() = default;
void Base() {
if (this->isVeg) {
this->total += this->basePri;
cout << "Base Price :" << this->basePri << endl;
} else {
this->total += this->nonBasePr;
cout << "Non Veg Base : " << this->nonBasePr << endl;
}
}
void Cheese() {
if (this->isCheese) return;
if (this->isVeg) {
this->total += this->cheese;
cout << "Cheese Price :" << this->cheese << endl;
} else {
this->total += this->ncheese;
cout << "Non Veg Cheese : " << this->ncheese << endl;
}
this->isCheese = true;
}
// --------------------------------------------------------------------
// OOP PILLAR 4 (A): COMPILE-TIME POLYMORPHISM (Function Overloading)
// Same function name 'Topping', different parameter list.
// --------------------------------------------------------------------
void Topping() {
if (this->isTop) return;
if (this->isVeg) {
this->total += this->topping;
cout << "Topping Price :" << this->topping << endl;
} else {
this->total += this->ntopping;
cout << "Non Veg Topping : " << this->ntopping << endl;
}
this->isTop = true;
}
// Overloaded variant: accepts quantity of extra toppings
void Topping(int extraCount) {
Topping(); // Add standard topping first
int rate = this->isVeg ? this->topping : this->ntopping;
this->total += (extraCount * rate);
cout << "Extra Toppings (" << extraCount << ") Added: " << (extraCount * rate) << endl;
}
// --------------------------------------------------------------------
// OOP PILLAR 4 (B): RUNTIME POLYMORPHISM (Virtual Function)
// 'virtual' enables dynamic dispatch via vtable so derived classes can override.
// --------------------------------------------------------------------
virtual double getBill() {
int gst = this->total * 0.5;
cout << "Total:" << this->total << endl;
cout << "GST:" << gst << endl;
int totalPr = this->total + gst;
cout << "Bill To Pay:" << totalPr << endl;
cout << " " << endl;
return totalPr;
}
};
// ============================================================================
// OOP PILLAR 3: INHERITANCE (Derived Subclass)
// Models "IS-A" relationship: Deluxe IS A Pizza. Reuses Base, Cheese, Topping logic.
// ============================================================================
class Deluxe : public Pizza {
public:
// OOP CONCEPT: CONSTRUCTOR INITIALIZER LIST
// Passes initialization arguments upstream to the base class constructor.
Deluxe(bool isVeg) : Pizza(isVeg) {
Cheese();
Topping();
}
// --------------------------------------------------------------------
// OOP PILLAR 4 (C): RUNTIME POLYMORPHISM (Method Overriding)
// Replaces base implementation to provide a Deluxe combo discount.
// --------------------------------------------------------------------
double getBill() override {
cout << "[Deluxe Combo Applied: 50 Flat Discount]" << endl;
this->total = max(0, this->total - 50);
return Pizza::getBill(); // Calls base logic with adjusted total
}
};
int main() {
// ------------------------------------------------------------------------
// OBJECTS & METHOD OVERLOADING EXECUTION
// ------------------------------------------------------------------------
Pizza p1(false);
p1.Cheese();
p1.Topping(1); // Calls overloaded Topping(int) -> Compile-time Polymorphism
p1.getBill();
Deluxe dp(true);
// ------------------------------------------------------------------------
// RUNTIME POLYMORPHISM (Dynamic Dispatch via Base Pointer)
// Base-class pointer pointing to derived-class object invokes Deluxe::getBill()
// ------------------------------------------------------------------------
Pizza* ptr = &dp;
ptr->getBill(); // Executes Deluxe's overridden getBill() via vtable lookup
return 0;
}